<!DOCTYPE html>
<html lang=zh>
<head>
    <meta charset="utf-8">
    
    <title>LErry</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
    <meta name="description" content="记录生活点滴">
<meta property="og:type" content="website">
<meta property="og:title" content="LErry">
<meta property="og:url" content="https://www.itchina.top/page/4/index.html">
<meta property="og:site_name" content="LErry">
<meta property="og:description" content="记录生活点滴">
<meta property="og:locale" content="zh-CN">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="LErry">
<meta name="twitter:description" content="记录生活点滴">
    

    
        <link rel="alternate" href="/atom.xml" title="LErry" type="application/atom+xml" />
    

    
        <link rel="icon" href="/css/images/shortcut_icon.png" />
    

    <link rel="stylesheet" href="/libs/font-awesome/css/font-awesome.min.css">
    <link rel="stylesheet" href="/libs/open-sans/styles.css">
    <link rel="stylesheet" href="/libs/source-code-pro/styles.css">

    <link rel="stylesheet" href="/css/style.css">

    <script src="/libs/jquery/2.1.3/jquery.min.js"></script>
    
    
        <link rel="stylesheet" href="/libs/lightgallery/css/lightgallery.min.css">
    
    
        <link rel="stylesheet" href="/libs/justified-gallery/justifiedGallery.min.css">
    
    
    
    


</head>

<body>
    <div id="container">
        <header id="header">
    <div id="header-main" class="header-inner">
        <div class="outer">
            <a href="/" id="logo">
                <i class="logo"></i>
                <span class="site-title">LErry</span>
            </a>
            <nav id="main-nav">
                
                    <a class="main-nav-link" href="/.">主页</a>
                
                    <a class="main-nav-link" href="/freebooks">书籍</a>
                
                    <a class="main-nav-link" href="/tags">标签</a>
                
                    <a class="main-nav-link" href="/archives">归档</a>
                
                    <a class="main-nav-link" href="/aboutme">关于</a>
                
            </nav>
            
                
                <nav id="sub-nav">
                    <div class="profile" id="profile-nav">
                        <a id="profile-anchor" href="javascript:;">
                            <img class="avatar" src="/css/images/avatar.png" />
                            <i class="fa fa-caret-down"></i>
                        </a>
                    </div>
                </nav>
            
            <div id="search-form-wrap">

    <form class="search-form">
        <input type="text" class="ins-search-input search-form-input" placeholder="搜索" />
        <button type="submit" class="search-form-submit"></button>
    </form>
    <div class="ins-search">
    <div class="ins-search-mask"></div>
    <div class="ins-search-container">
        <div class="ins-input-wrapper">
            <input type="text" class="ins-search-input" placeholder="想要查找什么..." />
            <span class="ins-close ins-selectable"><i class="fa fa-times-circle"></i></span>
        </div>
        <div class="ins-section-wrapper">
            <div class="ins-section-container"></div>
        </div>
    </div>
</div>
<script>
(function (window) {
    var INSIGHT_CONFIG = {
        TRANSLATION: {
            POSTS: '文章',
            PAGES: '页面',
            CATEGORIES: '分类',
            TAGS: '标签',
            UNTITLED: '(未命名)',
        },
        ROOT_URL: '/',
        CONTENT_URL: '/content.json',
    };
    window.INSIGHT_CONFIG = INSIGHT_CONFIG;
})(window);
</script>
<script src="/js/insight.js"></script>

</div>
        </div>
    </div>
    <div id="main-nav-mobile" class="header-sub header-inner">
        <table class="menu outer">
            <tr>
                
                    <td><a class="main-nav-link" href="/.">主页</a></td>
                
                    <td><a class="main-nav-link" href="/freebooks">书籍</a></td>
                
                    <td><a class="main-nav-link" href="/tags">标签</a></td>
                
                    <td><a class="main-nav-link" href="/archives">归档</a></td>
                
                    <td><a class="main-nav-link" href="/aboutme">关于</a></td>
                
                <td>
                    
    <div class="search-form">
        <input type="text" class="ins-search-input search-form-input" placeholder="搜索" />
    </div>

                </td>
            </tr>
        </table>
    </div>
</header>

        <div class="outer">
            
                

<aside id="profile">
    <div class="inner profile-inner">
        <div class="base-info profile-block">
            <img id="avatar" src="/css/images/avatar.png" />
            <h2 id="name">LErry Li</h2>
            <h3 id="title">知我者谓我心忧，不知我者谓我何求</h3>
            <span id="location"><i class="fa fa-map-marker"></i>Shanghai, China</span>
            <a id="follow" target="_blank" href="https://github.com/lerry903">关注我</a>
        </div>
        <div class="article-info profile-block">
            <div class="article-info-block">
                65
                <span>文章</span>
            </div>
            <div class="article-info-block">
                54
                <span>标签</span>
            </div>
        </div>
        
        <div class="profile-block social-links">
            <table>
                <tr>
                    
                    
                    <td>
                        <a href="https://github.com/lerry903" target="_blank" title="github" class=tooltip>
                            <i class="fa fa-github"></i>
                        </a>
                    </td>
                    
                    <td>
                        <a href="mailto:lerryli@foxmail.com" target="_blank" title="envelope" class=tooltip>
                            <i class="fa fa-envelope"></i>
                        </a>
                    </td>
                    
                    <td>
                        <a href="http://wpa.qq.com/msgrd?v=3&uin=824444270&site=qq&menu=yes" target="_blank" title="qq" class=tooltip>
                            <i class="fa fa-qq"></i>
                        </a>
                    </td>
                    
                    <td>
                        <a href="https://weibo.com/5941010376" target="_blank" title="weibo" class=tooltip>
                            <i class="fa fa-weibo"></i>
                        </a>
                    </td>
                    
                    <td>
                        <a href="/atom.xml" target="_blank" title="rss" class=tooltip>
                            <i class="fa fa-rss"></i>
                        </a>
                    </td>
                    
                </tr>
            </table>
        </div>
        
    </div>
</aside>

            
            <section id="main">
    <article id="post-Redis集群方案介绍" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 itemprop="name">
            <a class="article-title" href="/2018/04/20/Redis集群方案介绍/">Redis集群方案介绍</a>
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/2018/04/20/Redis集群方案介绍/">
            <time datetime="2018-04-19T16:34:21.428Z" itemprop="datePublished">2018-04-20</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/Redis/">Redis</a>
    </div>

                        
                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <p><strong> 本文节选自《App 后台开发运维和架构实践》一书 </strong></p>
<p>由于Redis出众的性能，其在众多的移动互联网企业中得到广泛的应用。Redis在3.0版本前只支持单实例模式，虽然现在的服务器<br>内存可以到100GB、200GB的规模，但是单实例模式限制了Redis没法满足业务的需求（例如新浪微博就曾经用Redis存储了超过1TB的数<br>据）。Redis的开发者Antirez早在博客上就提出在Redis<br>3.0版本中加入集群的功能，但3.0版本等到2015年才发布正式版。各大企业在3.0版本还没发布前为了解决Redis的存储瓶颈，纷纷推出了各自的<br>Redis集群方案。这些方案的核心思想是把数据分片（sharding）存储在多个Redis实例中，每一片就是一个Redis实例。</p>
<p>下面介绍Redis的集群方案。</p>
<p><strong> 1.客户端分片 </strong></p>
<p>客户端分片是把分片的逻辑放在Redis客户端实现，通过Redis客户端预先定义好的路由规则，把对Key的访问转发到不同的Redis实例中，最后把返回结果汇集<br>。这种方案的模式如图1所示。</p>
<p><img src="http://img.mp.itc.cn/upload/20160602/cccf7954e02f4cd5bb4ccc0e4b41a41e_th.j
pg" alt=""></p>
<p>_ 图1 客户端分片的模式 _</p>
<p>客户端分片的好处是所有的逻辑都是可控的，不依赖于第三方分布式中间件。开发人员清楚怎么实现分片、路由的规则，不用担心踩坑。</p>
<p>客户端分片方案有下面这些缺点。</p>
<ul>
<li><p>这是一种静态的分片方案，需要增加或者减少Redis实例的数量，需要手工调整分片的程序。 </p>
</li>
<li><p>可运维性差，集群的数据出了任何问题都需要运维人员和开发人员一起合作，减缓了解决问题的速度，增加了跨部门沟通的成本。 </p>
</li>
<li><p>在不同的客户端程序中，维护相同的分片逻辑成本巨大。例如，系统中有两套业务系统共用一套Redis集群，一套业务系统用Java实现， 另一套业务系统用PHP实现。为了保证分片逻辑的一致性，在Java客户端中实现的分片逻辑也需要在PHP客户端实现一次。相同的逻辑在不同的系统中分别 实现，这种设计本来就非常糟糕，而且需要耗费巨大的开发成本保证两套业务系统分片逻辑的一致性。 </p>
</li>
</ul>
<p><strong> 2.Twemproxy  </strong></p>
<p>Twemproxy是由Twitter开源的Redis代理，其基本原理是：Redis客户端把请求发送到Twemproxy，Twemproxy根据路由规则发送到<br>正确的Redis实例，最后Twemproxy把结果汇集返回给客户端。</p>
<p>Twemproxy通过引入一个代理层，将多个Redis实例进行统一管理，使Redis客户端只需要在Twemproxy上进行操作，而不需要关心后面有多少个Re<br>dis实例，从而实现了Redis集群。</p>
<p>Twemproxy集群架构如图2所示。</p>
<p><img src="http://img.mp.itc.cn/upload/20160602/0a782ef70afa460d862121a714811bf6_th.j
pg" alt=""></p>
<p>_ 图2Twemproxy集群架构  _</p>
<p>Twemproxy的优点如下。</p>
<ul>
<li><p>客户端像连接Redis实例一样连接Twemproxy，不需要改任何的代码逻辑。 </p>
</li>
<li><p>支持无效Redis实例的自动删除。 </p>
</li>
<li><p>Twemproxy与Redis实例保持连接，减少了客户端与Redis实例的连接数。 </p>
</li>
</ul>
<p>Twemproxy有如下不足。</p>
<ul>
<li><p>由于Redis客户端的每个请求都经过Twemproxy代理才能到达Redis服务器，这个过程中会产生性能损失。 </p>
</li>
<li><p>没有友好的监控管理后台界面，不利于运维监控。 </p>
</li>
<li><p>最大的问题是Twemproxy无法平滑地增加Redis实例。对于运维人员来说，当因为业务需要增加Redis实例时工作量非常大。 </p>
</li>
</ul>
<p>Twemproxy作为最被广泛使用、最久经考验、稳定性最高的Redis代理，在业界被广泛使用。</p>
<p><strong> 3.Codis  </strong></p>
<p>Twemproxy不能平滑增加Redis实例的问题带来了很大的不便，于是豌豆荚自主研发了Codis，一个支持平滑增加Redis实例的Redis代理软件，其基<br>于Go和C语言开发，并于2014年11月在GitHub上开源。</p>
<p>Codis包含下面4个部分。</p>
<ul>
<li><p>Codis Proxy：Redis客户端连接到Redis实例的代理，实现了Redis的协议，Redis客户端连接到Codis Proxy进行各种操作。Codis Proxy是无状态的，可以用Keepalived等负载均衡软件部署多个Codis Proxy实现高可用。 </p>
</li>
<li><p>CodisRedis：Codis项目维护的Redis分支，添加了slot和原子的数据迁移命令。Codis上层的 Codis Proxy和Codisconfig只有与这个版本的Redis通信才能正常运行。 </p>
</li>
<li><p>Codisconfig：Codis管理工具。可以执行添加删除CodisRedis节点、添加删除Codis Proxy、数据迁移等操作。另外，Codisconfig自带了HTTP server，里面集成了一个管理界面，方便运维人员观察Codis集群的状态和进行相关的操作，极大提高了运维的方便性，弥补了Twemproxy的缺 点。 </p>
</li>
<li><p>ZooKeeper：分布式的、开源的应用程序协调服务，是Hadoop和Hbase的重要组件，其为分布式应用提供一致性服务，提供的 功能包括：配置维护、名字服务、分布式同步、组服务等。Codis依赖于ZooKeeper存储数据路由表的信息和Codis Proxy节点的元信息。另外，Codisconfig发起的命令都会通过ZooKeeper同步到CodisProxy的节点。 </p>
</li>
</ul>
<p>Codis的架构如图3所示。</p>
<p><img src="http://img.mp.itc.cn/upload/20160602/ea48e6280d38466485a3c9fedb58d71a_th.j
pg" alt=""></p>
<p>_ 图3Codis的架构图 _</p>
<p>在图3的Codis的架构图中，Codis引入了Redis Server<br>Group，其通过指定一个主CodisRedis和一个或多个从CodisRedis，实现了Redis集群的高可用。当一个主CodisRedis挂<br>掉时，Codis不会自动把一个从CodisRedis提升为主CodisRedis，这涉及数据的一致性问题（Redis本身的数据同步是采用主从异步<br>复制，当数据在主CodisRedis写入成功时，从CodisRedis是否已读入这个数据是没法保证的），需要管理员在管理界面上手动把从<br>CodisRedis提升为主CodisRedis。</p>
<p>如果觉得麻烦，豌豆荚也提供了一个工具Codis-<br>ha，这个工具会在检测到主CodisRedis挂掉的时候将其下线并提升一个从CodisRedis为主CodisRedis。</p>
<p>Codis中采用预分片的形式，启动的时候就创建了1024个slot，1个slot相当于1个箱子，每个箱子有固定的编号，范围是<br>1~1024。slot这个箱子用作存放Key，至于Key存放到哪个箱子，可以通过算法“crc32(key)%1024”获得一个数字，这个数字的范<br>围一定是1~1024之间，Key就放到这个数字对应的slot。例如，如果某个Key通过算法“crc32(key)%1024”得到的数字是5，就放<br>到编码为5的slot（箱子）。1个slot只能放1个Redis Server Group，不能把1个slot放到多个Redis Server<br>Group中。1个Redis Server<br>Group最少可以存放1个slot，最大可以存放1024个slot。因此，Codis中最多可以指定1024个Redis Server Group。</p>
<p>Codis最大的优势在于支持平滑增加（减少）Redis Server Group（Redis实例），能安全、透明地迁移数据，这也是Codis<br>有别于Twemproxy等静态分布式 Redis 解决方案的地方。Codis增加了Redis Server<br>Group后，就牵涉到slot的迁移问题。例如，系统有两个Redis Server Group，Redis Server<br>Group和slot的对应关系如下。</p>
<p>Redis Server Group</p>
<p>slot</p>
<p>1</p>
<p>1~500</p>
<p>2</p>
<p>501~1024</p>
<p>当增加了一个Redis Server Group，slot就要重新分配了。Codis分配slot有两种方法。</p>
<p>第一种：通过Codis管理工具Codisconfig手动重新分配，指定每个Redis Server Group所对应的slot的范围，例如可以指定Redis<br>Server Group和slot的新的对应关系如下。</p>
<p>Redis Server Group</p>
<p>slot</p>
<p>1</p>
<p>1~500</p>
<p>2</p>
<p>501~700</p>
<p>3</p>
<p>701~1024</p>
<p>第二种：通过Codis管理工具Codisconfig的rebalance功能，会自动根据每个Redis Server<br>Group的内存对slot进行迁移，以实现数据的均衡。</p>
<p><strong> 4.Redis 3.0集群  </strong></p>
<p>Redis 3.0集群采用了P2P的模式，完全去中心化。Redis把所有的Key分成了16384个slot，每个Redis实例负责其中一部分slot。集群中<br>的所有信息（节点、端口、slot等），都通过节点之间定期的数据交换而更新。</p>
<p>Redis客户端在任意一个Redis实例发出请求，如果所需数据不在该实例中，通过重定向命令引导客户端访问所需的实例。</p>
<p>Redis 3.0集群的工作流程如图4所示。</p>
<p><img src="http://img.mp.itc.cn/upload/20160602/9bcc2b9eb8294561ad146c247c0b9d75_th.j
pg" alt=""></p>
<p>_ 图4Redis 3.0集群的工作流程图 _</p>
<p>如图4所示Redis集群内的机器定期交换数据，工作流程如下。</p>
<p>（1） Redis客户端在Redis2实例上访问某个数据。</p>
<p>（2） 在Redis2内发现这个数据是在Redis3这个实例中，给Redis客户端发送一个重定向的命令。</p>
<p>（3） Redis客户端收到重定向命令后，访问Redis3实例获取所需的数据。</p>
<p>Redis 3.0的集群方案有以下两个问题。</p>
<ul>
<li><p>一个Redis实例具备了“数据存储”和“路由重定向”，完全去中心化的设计。这带来的好处是部署非常简单，直接部署Redis就行，不 像Codis有那么多的组件和依赖。但带来的问题是很难对业务进行无痛的升级，如果哪天Redis集群出了什么严重的Bug，就只能回滚整个Redis集 群。 </p>
</li>
<li><p>对协议进行了较大的修改，对应的Redis客户端也需要升级。升级Redis客户端后谁能确保没有Bug？而且对于线上已经大规模运行的业务，升级代码中的Redis客户端也是一个很麻烦的事情。 </p>
</li>
</ul>
<p>综合上面所述的两个问题，Redis 3.0集群在业界并没有被大规模使用。</p>
<p><strong> 5.云服务器上的集群服务  </strong></p>
<p>国内的云服务器提供商阿里云、UCloud等均推出了基于Redis的云存储服务。</p>
<p>这个服务的特性如下。</p>
<p>（1）动态扩容</p>
<p>用户可以通过控制面板升级所需的Redis存储空间，扩容的过程中服务部不需要中断或停止，整个扩容过程对用户透明、无感知，这点是非常实用的，在前面介绍的方案中，<br>解决Redis平滑扩容是个很烦琐的任务，现在按几下鼠标就能搞定，大大减少了运维的负担。</p>
<p>（2）数据多备</p>
<p>数据保存在一主一备两台机器中，其中一台机器宕机了，数据还在另外一台机器上有备份。</p>
<p>（3）自动容灾</p>
<p>主机宕机后系统能自动检测并切换到备机上，实现服务的高可用。</p>
<p>（4）实惠</p>
<p>很多情况下为了使Redis的性能更高，需要购买一台专门的服务器用于Redis的存储服务，但这样子CPU、内存等资源就浪费了，购买Redis云存储服务就很好地<br>解决了这个问题。</p>
<p>有了Redis云存储服务，能使App后台开发人员从烦琐运维中解放出来。App后台要搭建一个高可用、高性能的Redis服务，需要投入相当的运维成本和精力。如果<br>使用云存储服务，就没必要投入这些成本和精力，可以让App后台开发人员更专注于业务。</p>

        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    
        <a href="https://www.itchina.top/2018/04/20/Redis集群方案介绍/#comments" id="sourceId::2018/04/20/Redis集群方案介绍/" class="article-comment-link cy_cmt_count">评论</a>
    

        </footer>
    </div>
    
</article>



    <article id="post-python数据分析之numpy初始化（一）" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 itemprop="name">
            <a class="article-title" href="/2018/04/20/python数据分析之numpy初始化（一）/">python数据分析之numpy初始化（一）</a>
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/2018/04/20/python数据分析之numpy初始化（一）/">
            <time datetime="2018-04-19T16:34:21.427Z" itemprop="datePublished">2018-04-20</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/cnn图片数据处理、显示/">cnn图片数据处理、显示</a><i class="fa fa-angle-right"></i><a class="article-category-link" href="/categories/cnn图片数据处理、显示/python数据分析/">python数据分析</a>
    </div>

                        
    <div class="article-tag">
        <i class="fa fa-tag"></i>
        <a class="tag-link" href="/tags/numpy/">numpy</a>, <a class="tag-link" href="/tags/数据分析/">数据分析</a>
    </div>

                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <p>以下都用numpy的标准“import numpy as np”<br>1.numpy是同构数据多维容器，同构即数据类型相同<br>2.初始化：  </p>
<p>2.1  np.arange([start,] end [, step])  #与list的range相似</p>
<pre><code> &gt;&gt;&gt; np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
&gt;&gt;&gt; np.arange(1, 10, 2)
array([1, 3, 5, 7, 9])
</code></pre><p>2.2  np.zeros(tupleA)  #产生一个tupleA维度大小的矩阵，且初始全为0  </p>
<pre><code>&gt;&gt;&gt; np.zeros((4))
array([ 0.,  0.,  0.,  0.])
&gt;&gt;&gt; np.zeros((4,2))
array([[ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.]])
</code></pre><p>2.3  np.ones(tupleA)  #与上面类似，只是初始化全为1</p>
<pre><code>&gt;&gt;&gt; np.ones((4))
array([ 1.,  1.,  1.,  1.])
&gt;&gt;&gt; np.ones((4,2))
array([[ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.]])
</code></pre><p>2.4  np.empty(tupleA)  #与上面类似，只是初始化值是不确定的（并不是你以为的0！！！！）  </p>
<pre><code>&gt;&gt;&gt; np.empty((4))
array([  1.73154357e-316,   4.71627160e-317,   0.00000000e+000,
         4.94065646e-324])
&gt;&gt;&gt; np.empty((3,2))
array([[  0.00000000e+000,   0.00000000e+000],
       [  6.94647584e-310,   6.94647586e-310],
       [  6.94647586e-310,   6.94647586e-310],
</code></pre><p>2.5  np.array(listA)  #把listA转成np，listA只是一个统称，只要是序列化的都可以，还可以是其他np  </p>
<pre><code>&gt;&gt;&gt; np.array([[1, 2, 3], [4, 3, 2]])
array([[1, 2, 3],
       [4, 3, 2]])
&gt;&gt;&gt; npA = np.array([[1, 2, 3], [4, 3, 2]])
&gt;&gt;&gt; npA
array([[1, 2, 3],
       [4, 3, 2]])
&gt;&gt;&gt; npB = np.array([[1, 2, 3], [4, 3, 2.0]])
&gt;&gt;&gt; npB
array([[ 1.,  2.,  3.],
       [ 4.,  3.,  2.]])
  np.array会自动找到最适合listA数据类型转给np:
&gt;&gt;&gt; npA.dtype
dtype(&apos;int64&apos;)
&gt;&gt;&gt; npB.dtype
dtype(&apos;float64&apos;)
</code></pre><p>但其实，  np初始化时没有特别说明都会被默认是float64  ，如前四种</p>
<p>2.6其他：  ones_like(npA);zeros_like(npA);empty_like(npA)  </p>
<pre><code>&gt;&gt;&gt; npB = np.array([[1, 2, 3], [4, 3, 2.0]])
&gt;&gt;&gt; np.ones_like(npB)
array([[ 1.,  1.,  1.],
       [ 1.,  1.,  1.]])
&gt;&gt;&gt; np.zeros_like(npB)
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  0.]])
&gt;&gt;&gt; np.empty_like(npB)
array([[  0.00000000e+000,   0.00000000e+000,   1.56491143e-316],
       [  6.94647850e-310,   6.94635322e-310,   1.72361006e-316]])
&gt;&gt;&gt; np.identity(3)
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
&gt;&gt;&gt; np.eye(3, k = -1)#变化k的值试试看
array([[ 0.,  0.,  0.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.]])
</code></pre>
        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    
        <a href="https://www.itchina.top/2018/04/20/python数据分析之numpy初始化（一）/#comments" id="sourceId::2018/04/20/python数据分析之numpy初始化（一）/" class="article-comment-link cy_cmt_count">评论</a>
    

        </footer>
    </div>
    
</article>



    <article id="post-nginx配置文件详解" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 itemprop="name">
            <a class="article-title" href="/2018/04/20/nginx配置文件详解/">nginx配置文件详解</a>
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/2018/04/20/nginx配置文件详解/">
            <time datetime="2018-04-19T16:34:21.427Z" itemprop="datePublished">2018-04-20</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/Linux/">Linux</a>
    </div>

                        
    <div class="article-tag">
        <i class="fa fa-tag"></i>
        <a class="tag-link" href="/tags/linux/">linux</a>, <a class="tag-link" href="/tags/nginx/">nginx</a>
    </div>

                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <p><strong> #运行用户 </strong>   </p>
<p>** user www-data;   </p>
<p>#启动进程,通常设置成和cpu的数量相等<br>worker_processes  1; <strong>  
</strong> #全局错误日志及PID文件<br>error_log  /var/log/nginx/error.log;<br>pid        /var/run/nginx.pid;  </p>
<p><strong>   
</strong> #工作模式及连接数上限<br>events {<br>use   epoll;             #epoll是多路复用IO(I/O<br>Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能<br>worker_connections  1024;#单个后台worker process进程的最大并发链接数  </p>
<h1 id="multi-accept-on"><a href="#multi-accept-on" class="headerlink" title="multi_accept on;"></a>multi_accept on;</h1><p>}<br><strong>   
</strong> #设定http服务器，利用它的反向代理功能提供负载均衡支持<br>http {  </p>
<p>#设定mime类型,类型由mime.type文件定义<br>include       /etc/nginx/mime.types;<br>default_type  application/octet-stream;  </p>
<p>#设定日志格式<br>access_log    /var/log/nginx/access.log; <strong>  
</strong> #sendfile 指令指定 nginx 是否调用 sendfile 函数（zero copy 方式）来输出文件，对于普通应用，   </p>
<p>#必须设为 on,如果用来进行下载等应用磁盘IO重负载应用，可设置为 off，以平衡磁盘与网络I/O处理速度，降低系统的uptime.<br>sendfile        on;  </p>
<p>#tcp_nopush     on; <strong>  
</strong> #连接超时时间   </p>
<p>#keepalive_timeout  0;<br>keepalive_timeout  65;<br>tcp_nodelay        on;  </p>
<p>#开启gzip压缩<br>gzip  on;<br>gzip_disable “MSIE [1-6]\.(?!.<em>SV1)”; <strong>  
</strong> #设定请求缓冲<br>client_header_buffer_size    1k;<br>large_client_header_buffers  4 4k; <strong>  
</strong> include /etc/nginx/conf.d/</em>.conf;<br>include /etc/nginx/sites-enabled/*; <strong>  
</strong> #设定负载均衡的服务器列表<br>upstream mysvr {  </p>
<p>#weigth参数表示权值，权值越高被分配到的几率越大  </p>
<p>#本机上的Squid开启3128端口<br>server 192.168.8.1:3128 weight=5;<br>server 192.168.8.2:80  weight=1;<br>server 192.168.8.3:80  weight=6;<br>} **  </p>
<p>** server {   </p>
<p>#侦听80端口<br>listen       80;  </p>
<p>#定义使用 <strong> <a href="http://www.xx.com/" target="_blank" rel="noopener"> www.xx.com </a> </strong> 访问<br>server_name <a href="http://www.xx.com/" target="_blank" rel="noopener"> www.xx.com </a> ; <strong>  
</strong> #设定本虚拟主机的访问日志<br>access_log  logs/ <a href="http://www.xx.com.access.log/" target="_blank" rel="noopener"> www.xx.com.access.log </a><br>main; <strong>  
</strong> #默认请求<br>location / {<br>root   /root;      #定义服务器的默认网站根目录位置<br>index index.php index.html index.htm;   #定义首页索引文件的名称 <strong>  
</strong> fastcgi_pass <a href="http://www.xx.com/" target="_blank" rel="noopener"> www.xx.com </a> ;<br>fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;<br>include /etc/nginx/fastcgi_params;<br>} <strong>  
</strong> # 定义错误提示页面<br>error_page   500 502 503 504 /50x.html;<br>location = /50x.html {<br>root   /root;<br>} <strong>  
</strong> #静态文件，nginx自己处理<br>location ~ ^/(images|javascript|js|css|flash|media|static)/ {<br>root /var/www/virtual/htdocs;  </p>
<p>#过期30天，静态文件不怎么更新，过期可以设大一点，如果频繁更新，则可以设置得小一点。<br>expires 30d;<br>}  </p>
<p>#PHP 脚本请求全部转发到 FastCGI处理. 使用FastCGI默认配置.<br>location ~ \.php$ {<br>root /root;<br>fastcgi_pass 127.0.0.1:9000;<br>fastcgi_index index.php;<br>fastcgi_param SCRIPT_FILENAME /home/www/www$fastcgi_script_name;<br>include fastcgi_params;<br>}  </p>
<p>#设定查看Nginx状态的地址<br>location /NginxStatus {<br>stub_status            on;<br>access_log              on;<br>auth_basic              “NginxStatus”;<br>auth_basic_user_file  conf/htpasswd;<br>}  </p>
<p>#禁止访问 .htxxx 文件<br>location ~ /\.ht {<br>deny all;<br>}  </p>
<p>}<br><strong>   
</strong> } **</p>

        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    
        <a href="https://www.itchina.top/2018/04/20/nginx配置文件详解/#comments" id="sourceId::2018/04/20/nginx配置文件详解/" class="article-comment-link cy_cmt_count">评论</a>
    

        </footer>
    </div>
    
</article>



    <article id="post-MySQL+Heartbeat+DRBD构建高可用MySQL环境" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 itemprop="name">
            <a class="article-title" href="/2018/04/20/MySQL+Heartbeat+DRBD构建高可用MySQL环境/">MySQL+Heartbeat+DRBD构建高可用MySQL环境</a>
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/2018/04/20/MySQL+Heartbeat+DRBD构建高可用MySQL环境/">
            <time datetime="2018-04-19T16:34:21.425Z" itemprop="datePublished">2018-04-20</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/数据库/">数据库</a><i class="fa fa-angle-right"></i><a class="article-category-link" href="/categories/数据库/集群/">集群</a>
    </div>

                        
    <div class="article-tag">
        <i class="fa fa-tag"></i>
        <a class="tag-link" href="/tags/mysql/">mysql</a>
    </div>

                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <p>Distributed Replicated Block Device(DRBD)是一个用软件实现的、无共享的、服务器之间镜像块设备内容的存储复制解决方案。<br>数据镜像：实时、透明、同步（所有服务器都成功后返回）、异步（本地服务器成功后返回）</p>
<p>DBRD的核心功能通过Linux的内核实现，最接近系统的IO栈，但它不能神奇地添加上层的功能比如检测到EXT3文件系统的崩溃。</p>
<p>DBRD的位置处于文件系统以下，比文件系统更加靠近操作系统内核及IO栈。</p>
<p>——《百度百科》</p>
<p>实验环境：</p>
<p>主 192.168.43.128 drbd-M   CentOS 5.4 64bit</p>
<p>从 192.168.43.129 drbd-S    CentOS5.4 64bit</p>
<p>准备工作：</p>
<p>Vim /etc/hosts</p>
<p>192.168.43.129 drbd-M</p>
<p>192.168.43.130 drbd-S</p>
<p>修改hostname名，</p>
<p>主：hostname drbd-M</p>
<p>从：hostname drbd-S</p>
<p>确保与uname -n输出一致。PS：很重要，后面的drbd和heartbeat都要依赖于主机名来通信。</p>
<p>搭建环境，采用yum安装：</p>
<pre><code>    1. # yum install -y drbd83 kmod-drbd83 
2.  
3. # yum search heartbeat* 
4.  
5. heartbeat所需的安装包主要有以下几个： 
6.  
7. heartbeat-devel-2.1.3-3.el5.centos 
8.  
9. heartbeat-stonith-2.1.3-3.el5.centos 
10.  
11. heartbeat-gui-2.1.3-3.el5.centos 
12.  
13. heartbeat-ldirectord-2.1.3-3.el5.centos 
14.  
15. heartbeat-pils-2.1.3-3.el5.centos 
16.  
17. heartbeat-2.1.3-3.el5.centos 
</code></pre><p>一 DRBD的安装使用</p>
<p>加载安装drbd模块：</p>
<pre><code>1. # modprobe drbd 
</code></pre><p>检查是否加载成功：</p>
<pre><code>    1. # modprobe drbd 
2. drbd                  277272  2 
</code></pre><p>PS：一般使用yum安装的话系统会自动加载的，此步可以跳过，如果使用源码包编译就一定要记得这一步。</p>
<p>添加一块硬盘，存放数据，主从服务器的硬盘大小可以不一致，但是如果数据超过小的硬盘，后果自己考虑吧！这里添加的是一块2G的硬盘，设备名称为/dev/sdb2，<br>注意先别急着格式化。</p>
<p>开始drbd的配置：</p>
<p>drbd主配置文件，很重要：</p>
<pre><code>    1. global {  
2. }  
3. common {  
4. syncer { rate 100M; }    //设置两个节点间的同步速率；  
5. } 
6.  
7. resource db {  
8. protocol C;     //定义当数据被写入块设备时候的一致性级别（数据同步协议），A、B、C三个级别，C为数据被确认写到本地磁盘和远程磁盘后返回，确认成功  
9. startup { wfc-timeout 0; degr-wfc-timeout 120; } 
10. disk { on-io-error detach; } 
11. syncer { rate 100M; } 
12.  
13. on drbd-M {  //节点名称一定要与hostname保持一致； 
14.   device /dev/drbd0;     //创建的虚拟磁盘 
15.   disk   /dev/sdb2;      //物理分区 
16.   address 192.168.43.129:7788;    //监听端口 
17.   meta-disk internal;         //局域网类型 
18.  
19. } 
20.  
21. on drbd-S { 
22.    device /dev/drbd0; 
23.    disk   /dev/sdb2; 
24.    address 192.168.43.130:7788; 
25.    meta-disk internal; 
26.    } 
27.  } 
</code></pre><p>检测配置文件：</p>
<pre><code>1. #drbdadm ajust db 
</code></pre><p>至此drbd已经配置完毕，以上步骤在主从服务器上都要做，而且drbd的配置文件要保持一致。</p>
<p>主服务器和从服务器上创建matadata：</p>
<pre><code>1. # drbdadm create-md all 
</code></pre><p>主从服务器启动drbd：</p>
<pre><code>1. # /etc/init.d/drbd start 
</code></pre><p>此时主从服务器之间开始同步数据，第一次的话时间会稍微长一些。</p>
<p>将drbd-M 设为主节点</p>
<p>第一次的话要使用：</p>
<pre><code>1. # drbdsetup /dev/drbd0 primary -o 
</code></pre><p>以后可以使用drbdadm  primary all命令。</p>
<p>将新创建的设备格式化并且挂载：</p>
<pre><code>    1. # mkfs.ext3 /dev/drbd0  //破坏文件系统：dd if=/dev/zero bs=1M of=/dev/sdb2;sync 
2. # mount /dev/drbd0 /data/  
3. # df –H 
</code></pre><p><img src="http://img1.51cto.com/attachment/201110/18/508999_1318
941951sZET.png" alt="wps_clip_image-17319"></p>
<p>在/data目录下创建文件进行测试：</p>
<pre><code>    1. # cd /data/ 
2. # mkdir linna 
3. # touch database 
4. # ls 
5. database  linna  lost+found 
</code></pre><p>下面进行测试：</p>
<p>drbd-M：</p>
<p>将主服务器降为从：</p>
<p>先卸载设备：</p>
<pre><code>    1. # umount /data/ 
2. # drbdadm secondary all 
</code></pre><p>PS:临时切断节点之间的连接可以使用：#drbdadm connect all</p>
<p>查看系统日志/var/log/message:</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318941953DHE2.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_13
18941960nzKW.png" alt="wps_clip_image-27705">
</a></p>
<p>Drbd-S：</p>
<p>我们再将从服务器提升为主服务器看下数据能否同步过来：</p>
<pre><code>1. # drbdadm primary all 
</code></pre><p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318941962MTDi.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_13
18941963zcXu.png" alt="wps_clip_image-11042">
</a></p>
<pre><code>    1. # mount /dev/drbd0 /data 
2. # cd /data/ 
</code></pre><p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318941963A4Be.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_131
894196393ni.png" alt="wps_clip_image-5498">
</a></p>
<p>看，数据已经同步过来了！</p>
<p>我们可以通过查看/proc/drbd来监控主从节点间之间数据同步的过程：</p>
<pre><code>1. #Watch  -n 10 ‘cat /proc/drbd’ 
</code></pre><p>二 MySQL+Heartbeat+DRBD构建高可用环境</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318941969Cg0A.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_13
18941974XLR4.png" alt="wps_clip_image-11886">
</a></p>
<p>图 MySQL+Heartbeat+DRBD构建高可用MySQL</p>
<p>1 Heartbeat主配置文件/etc/ha.d/ha.cf：</p>
<pre><code>    1. # cat /etc/ha.d/ha.cf 
2. logfacility local0       //定义日志，使用syslog； 
3. keepalive 2           //定义心跳频率； 
4. deadtime 15          //如果其他节点15S内没有回应，则确认其死     亡；       
5. warntime 5           //确认一个节点连接不上5S之后将警告信息写入日志；   
6. initdead 120          //在其他节点死掉之后，系统启动前需要等待的时间，一般为deadtime的两倍； 
7. udpport 694          // 用来通信的端口； 
8. bcast eth0            // 在eth0上进行心跳测试 
9. watchdog /dev/watchdog  //可选项 
10. auto_failback off        // 设置当死亡节点恢复正常之后是否重新启用；容易发生数据不一致的情况，必须项，不然后面hb_standby命令无法使用； 
11. node drbd-M 
12. node drbd-S 
13. respawn hacluster /usr/lib64/heartbeat/ipfail 
</code></pre><p>2 设置两个节点之间的通信密钥：</p>
<pre><code>    1. #cat authkeys 
2. auth 3 
3. 3 md5 Hello! 
</code></pre><p>3 定义资源：</p>
<pre><code>    1. # cat haresources 
2. drbd-M drbddisk Filesystem::/dev/drbd0::/data::ext3 mysqld 192.168.43.20  
</code></pre><p>drbd-M    //主节点；</p>
<p>drbddisk  Filesystem::/dev/drbd0::/data::ext3 mysqld   //定义Heartbeat需要管理的资源，并且<br>每一部分在/etc/ha.d/haresources.d下有对应的脚本；如果主节点失效，备节点将通过执行这些脚本来启用资源；如果脚本有参数可以使用“：：”来<br>进行分割；</p>
<p>drbddisk  管理drbd资源的脚本；</p>
<p>filesystem 管理文件系统资源的脚本，后面参数定义drbd设备，挂载点，文件系统类型</p>
<p>mysqld  管理mysql的脚本，需要从/etc/init.d/mysqld 拷贝</p>
<p>192.168.43.20  //VIP,用来连接MySQL的IP，当Heartbeat启用之后会自动分配；</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318941974BcIu.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_13
1894197650rB.png" alt="wps_clip_image-13327">
</a></p>
<p>图 Resource.d 下的内容</p>
<p>在主从节点上启动Heartbeat</p>
<pre><code>1. # /etc/init.d/heartbeat start 
</code></pre><p>查看下资源启动情况：</p>
<p>先看下主节点drbd-M的日志：</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318941979QZD3.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_13
18941983UU3T.png" alt="wps_clip_image-26722">
</a></p>
<p>再看下drbd-S的日志，已经处在监听等待状态：</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318941985KsoM.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_131
8941989pSUV.png" alt="wps_clip_image-6070">
</a></p>
<p>虚拟IP已经启动：</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318941992fcfZ.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_131
89419945gMv.png" alt="wps_clip_image-4355">
</a></p>
<p>Drbd和MySQL的端口已经在监听：</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318941994NkcE.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_131
8941994iO5A.png" alt="wps_clip_image-2739">
</a></p>
<p>主节点/data目录下：</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318941997DeFl.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_13
18941997Bqw3.png" alt="wps_clip_image-17322">
</a></p>
<p>我们切换到drbd-S来试一下，看资源能不能切换过来：</p>
<p>使用/usr/lib64/heartbeat/hb_standby命令可以来模拟主节点死掉的情况。</p>
<pre><code>1. 2011/07/18_20:49:53 Going standby [all]. 
</code></pre><p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318942000LO98.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_131
8942004Bt9m.png" alt="wps_clip_image-5686">
</a></p>
<p>从服务器drbd-S日志：</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318942005EJwm.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_13
18942008sp6F.png" alt="wps_clip_image-28906">
</a></p>
<p>再看下资源是否已经抢占过来：</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318942010VtKs.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_13
18942011pQOs.png" alt="wps_clip_image-29561">
</a></p>
<p>/data目录下的文件：</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318942011tszz.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_13
18942013G2Ny.png" alt="wps_clip_image-22200">
</a></p>
<p>PS:Heartbeat启动之前必须保证drbd服务已经启动，并且主服务器已经设置为primary并成功挂载/dev/drbd0.不然主服务器Heartbe<br>at在启动的时候会提示找不到/dev/drbd0设备，并造成其他的资源也无法启动的情况。</p>
<p><a href="http://img1.51cto.com/attachment/201110/18/508999_1318942014IJ56.png" target="_blank" rel="noopener"> <img src="http://img1.51cto.com/attachment/201110/18/508999_13
189420167pAp.png" alt="wps_clip_image-17254">
</a></p>
<p>PS：心跳探测和数据复制不建议在同一个网卡上进行，本实验只是为了方便采取了这样的方式。</p>
<p>dopd进程：当主从节点之间的失去连接，那么主从节点之间的数据就无法同步，就会发生从节点的数据过期的情况（数据不一致的情况）。如果此时主服务器发生宕机的情况<br>，那么dopd进程会阻止从服务器提升为主服务器。具体实现：</p>
<p>1 修改/etc/ha.d/ha.cf 文件：</p>
<pre><code>    1. respawn  hacluster /usr/lib64/heartbeat/dopd 
2. apiauth  dopd gid=haclient uid=hacluster  
</code></pre><p>2 修改/etc/drbd.conf 文件：</p>
<pre><code>    1. common { 
2. handlers { 
3.          outdate-peer “/usr/lib64/heartbeat/drbd-peer-outdater”; 
4.       } 
5. } 
6. resource db { 
7. disk { 
8. Fencing resource-only; 
9.      } 
10.    } 
</code></pre><p>3 重新加载配置文件：</p>
<pre><code>    1. # /etc/init.d/heartbeat reload 
2. #/drbdadm adjust all 
</code></pre><p>MySQL+Heartbeat+DRBD方案可以单独使用，也可以在构建MySQL主从架构时实现主服务器的高可用，在此不再详细实现，有兴趣的朋友可以尝试一下（<br>完）！</p>
<p>参考文章：MySQL and DRBD Guide</p>
<p>本文出自 “ <a href="http://lyp0909.blog.51cto.com" target="_blank" rel="noopener"> 諸葛草廬 </a> ” 博客，请务必保留此出处 <a href="http://lyp0909.blog.51cto.com/508999/691435" target="_blank" rel="noopener"><br>http://lyp0909.blog.51cto.com/508999/691435
</a></p>

        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    
        <a href="https://www.itchina.top/2018/04/20/MySQL+Heartbeat+DRBD构建高可用MySQL环境/#comments" id="sourceId::2018/04/20/MySQL+Heartbeat+DRBD构建高可用MySQL环境/" class="article-comment-link cy_cmt_count">评论</a>
    

        </footer>
    </div>
    
</article>



    <article id="post-MySQL集群" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 itemprop="name">
            <a class="article-title" href="/2018/04/20/MySQL集群/">MySQL集群</a>
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/2018/04/20/MySQL集群/">
            <time datetime="2018-04-19T16:34:21.425Z" itemprop="datePublished">2018-04-20</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/数据库/">数据库</a>
    </div>

                        
    <div class="article-tag">
        <i class="fa fa-tag"></i>
        <a class="tag-link" href="/tags/mysql/">mysql</a>
    </div>

                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <p>Mysql Cluster7.4.6安装与配置</p>
<p>Mysql Cluster版本：mysql-cluster-gpl-7.4.6-linux-glibc2.5-x6_64.tar.gz</p>
<p>管理节点服务器1台</p>
<p>Sql服务器2台</p>
<p>Ndb服务器2台</p>
<p>首先修改所有服务器的hostname</p>
<p>Vi /etc/hosts</p>
<p>将节点服务器名配置为：MGM1</p>
<p>将Sql服务器配置为：SQL1，SQL2</p>
<p>将NDB服务器配置为：NDB1，NDB2</p>
<p>一、Sql节点以及Ndb节点安装步骤：</p>
<p>1.首先在节点服务器上安装Centos6.5，不要安装内置Mysql</p>
<p>2.  从官方网站上下载Mysql Cluster，这里使用到的版本为Mysql Cluster7.4.6</p>
<p>3.  创建用户群,groupadd mysql</p>
<p>4.  创建用户,useradd -g mysql mysql</p>
<p>5.  解压缩Mysql Cluster包，输入tar -zxvf mysql-cluster-gpl-7.4.6-linux-<br>glibc2.5-x6_64.tar.gz</p>
<p>6.  将解压缩后的包移入/usr/local内，输入cp mysql-cluster-gpl-7.4.6-linux-glibc2.5-x6_64<br>/usr/local/mysql</p>
<p>7.  进入mysql文件夹,输入cd /usr/local/mysql</p>
<p>8.  输入chown -R root *</p>
<p>9.  输入chown -R mysql data</p>
<p>10.  输入chgrp -R mysql *</p>
<p>11.  安装mysql-cluster，输入scripts/mysql_install_db –user=mysql</p>
<p>12.  注册mysql的service，输入cp support-files/mysql.server /etc/rc.d/init.d/mysqld</p>
<p>13.  chmod +x /etc/rc.d/init.d/mysqld</p>
<p>14.  chkconfig –add mysqld</p>
<p>15.  运行service mysqld start启动mysql</p>
<p>二、管理节点安装步骤：</p>
<p>1.在管理节点服务器完成上述sql节点和ndb节点安装步骤后，输入cd /usr/local/mysql进入目录</p>
<p>2.cp bin/ndb_mgm*/usr/local/bin</p>
<p>3.cd /usr/local/bin</p>
<p>4.chmod +x ndb_mgm*</p>
<p>三、  配置sql节点和ndb节点</p>
<p>mysql服务启动时会默认加载/etc/my.cnf作为其配置文件，要将一个mysql服务器配置成一个数据节点和SQL节点也非常的简单，这是配置前的my.c<br>nf的内容：</p>
<p>1.[client]</p>
<p>port=3306</p>
<p>socket=/tmp/mysql.sock</p>
<p>[mysqld]</p>
<p>basedir=/usr/local/mysql/</p>
<p>datadir=/usr/local/mysql/data</p>
<p>user= mysql</p>
<p>log-error=/var/lib/mysql/mysqld.err</p>
<p>2.  在此基础上在最下方分别加入以下语句：</p>
<p>a)  如果是NDB服务器的情况下输入：</p>
<p>ndbcluster</p>
<p>ndb-connectstring=  MGM1</p>
<p>b) 如果是SQL节点服务器的情况下输入</p>
<p>[mysql_cluster]</p>
<p>ndb-connectstring=  MGM1</p>
<p>注意所有服务器必须具有相同的配置</p>
<p>四、  管理节点服务器的配置</p>
<p>1.  cd /var/lib</p>
<p>2.  mkdir mysql-cluster</p>
<p>3.  vi config.ini，创建配置文件</p>
<p>4.  在config.ini文件中添加以下内容：</p>
<p>[NDBD DEFAULT]</p>
<p>NoOfReplicas=1    #每个数据节点的镜像数量</p>
<p>DataMemory=500M   #每个数据节点中给数据分配的内存</p>
<p>IndexMemory=300M  #每个数据节点中给索引分配的内存</p>
<p>[TCP DEFAULT]</p>
<p>portnumber=2202   #数据节点的默认连接端口</p>
<p>[NDB_MGMD]        #配置管理节点</p>
<p>hostname=MGM1</p>
<p>datadir=/var/lib/mysql-cluster/  #管理节点数据(日志)目录</p>
<p>[NDBD]            #数据节点配置</p>
<p>hostname=NDB1</p>
<p>datadir=/usr/local/mysql/data/   #数据节点目录</p>
<p>[NDBD]</p>
<p>hostname=NDB2</p>
<p>datadir=/usr/local/mysql/data/</p>
<p>[MYSQLD]   #SQL节点目录</p>
<p>hostname=SQL1</p>
<p>[MYSQLD]</p>
<p>hostname=SQL2</p>
<p>注释：</p>
<p>[NDBD DEFAULT]：表示每个数据节点的默认配置在每个节点的[NDBD]中不用再写这些选项，只能有一个。</p>
<p>[NDB_MGMD]：表示管理节点的配置，只有一个。</p>
<p>[NDBD]：表示每个数据节点的配置，可以有多个。</p>
<p>[MYSQLD]：表示SQL节点的配置，可以有多个，分别写上不同SQL节点的IP地址，也可以什么都不写，只保留一个空节点，表示任意一个IP地址都可以进行访问<br>，此节点的个数表明了可以用来连接数据节点的SQL节点总数。</p>
<p>五、  启动</p>
<p>1.  管理节点的启动：</p>
<p>a)  Mysql cluster需要各个节点进行启动后方能够工作，节点的启动顺序为：管理节点——》NDB数据节点——》Sql节点。因此首先启管理节点</p>
<p>b)  cd /usr/local/bin</p>
<p>c)  ndb_mgmd -f /var/lib/mysql-cluster/config.ini</p>
<p>d)  注意以上为第一次配置的情况下，如果新增节点，使用./  ndb_mgmd -f /var/lib/mysql-cluster/config.ini<br>–initial进行加载，不然添加的节点不会出现在集群中</p>
<p>e)  启动时可能会报个WARNING,如WARNING  – at line 7: [TCP] portnumber is<br>deprecated，这个不用管。可以正常工作的。</p>
<p>f)  启动后可以使用ndb_mgm -e show查看运行状态</p>
<p>2.  NDB节点的启动</p>
<p>a)  cd /usr/local/bin</p>
<p>b)  ./ndbd –initial</p>
<p>c)  如果出现类似以下信息则表明成功连接到管理节点服务器：</p>
<p>2015-06-25 12:48:03 [ndbd] INFO     – Angel connected to ‘MGM1:1186’</p>
<p>2015-06-25 12:48:03 [ndbd] INFO     – Angel allocated nodeid: 3</p>
<p>3.  SQL节点的启动：</p>
<p>a)  service mysqld start</p>
<p>4.  客户端管理</p>
<p>a)  在管理服务器中输入cd /usr/local/bin/</p>
<p>b)  ./ndb_mgm</p>
<p>c)  在ndb_mgm&gt; 提示符下输入show：</p>
<p>ndb_mgm&gt; show</p>
<p>ClusterConfiguration</p>
<p>-——————–</p>
<p>[ndbd(NDB)]     2 node(s)</p>
<p>id=2    @NDB1 (mysql-  5.6.24  ndb-  7.4.6  ,Nodegroup:0,Master)</p>
<p>id=3    @NDB2 (mysql-  5.6.24  ndb-  7.4.6  ,Nodegroup:1)</p>
<p>[ndb_mgmd(MGM)]1 node(s)</p>
<p>id=1    @MGM1  (mysql-  5.6.24  ndb-  7.4.6  )</p>
<p>[mysqld(API)]   2 node(s)</p>
<p>id=4    @SQL1  (mysql-  5.6.24  ndb-  7.4.6  )</p>
<p>id=5    @SQL2  (mysql-  5.6.24  ndb-  7.4.6  )</p>
<p>5.  关闭mysql cluster</p>
<p>a)  cd /usr/local/bin</p>
<p>b)  ./ndb_mgm -e shutdown</p>
<p>c)  虽然mysql cluster 关闭了，但是SQL节点的mysql服务并不会停止的。接下来就可以做各种试验了。</p>

        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    
        <a href="https://www.itchina.top/2018/04/20/MySQL集群/#comments" id="sourceId::2018/04/20/MySQL集群/" class="article-comment-link cy_cmt_count">评论</a>
    

        </footer>
    </div>
    
</article>



    <article id="post-Linux命令之find" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 itemprop="name">
            <a class="article-title" href="/2018/04/20/Linux命令之find/">Linux命令之find</a>
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/2018/04/20/Linux命令之find/">
            <time datetime="2018-04-19T16:34:21.424Z" itemprop="datePublished">2018-04-20</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/Linux/">Linux</a>
    </div>

                        
    <div class="article-tag">
        <i class="fa fa-tag"></i>
        <a class="tag-link" href="/tags/find/">find</a>, <a class="tag-link" href="/tags/linux/">linux</a>
    </div>

                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <p>Linux下的find命令用来在目录结构中搜索文件，并执行指定的操作。Linux下find命令提供了相当多的查找条件，功能很强大。即使系统中含有网络文件系统<br>( NFS)，find命令在该文件系统中同样有效。  </p>
<p>需要注意的是在运行一个非常消耗资源的find命令时，我们都倾向于把它放在后台执行，因为遍历一个大的文件系统可能会花费很长的时间(这里是指30G字节以上的文件<br>系统)。  </p>
<p>1. 想查看当前文件夹及子文件夹里文件名含有“log”字样的的文件  </p>
<h1 id="find-name-“-log”"><a href="#find-name-“-log”" class="headerlink" title="find . -name “*.log”"></a>find . -name “*.log”</h1><p>. ：表示当前目录</p>
<p>-name：表示要根据名称查找   </p>
<p>2. 想查看当前文件夹及子文件夹里有没有”xinsz”目录</p>
<h1 id="find-type-d-name-xinsz"><a href="#find-type-d-name-xinsz" class="headerlink" title="find . -type d -name xinsz"></a>find . -type d -name xinsz</h1><p>-type：表示设定类型，d表示文件夹类型，可以替换为f(普通文件)、l(链接文件) </p>
<p>3. 想找出当前文件夹及子文件夹里所有后缀是”.txt”的文件</p>
<h1 id="find-name-“-txt”"><a href="#find-name-“-txt”" class="headerlink" title="find . -name “*.txt”"></a>find . -name “*.txt”</h1><p>4. 想查找当前目录及其子文件夹中“roc”用户自己的文件有哪些</p>
<h1 id="find-user-roc"><a href="#find-user-roc" class="headerlink" title="find . -user roc"></a>find . -user roc</h1><p>-user：用于设定所属用户的名称，此处可替换为-group，即所属用户组的名称 </p>
<p>5. 想查找当前文件夹及子文件夹里权限设定为777的所有文件</p>
<h1 id="find-perm-777"><a href="#find-perm-777" class="headerlink" title="find . -perm 777"></a>find . -perm 777</h1><p>-perm：用于设定权限 </p>
<p>6. 想查找当前文件夹及子文件夹里的同时含有b字符和3字符的文件：用到正则表达式技术</p>
<h1 id="find-regex-‘-b-3’"><a href="#find-regex-‘-b-3’" class="headerlink" title="find . -regex ‘.b.3’"></a>find . -regex ‘.<em>b.</em>3’</h1><p>-regex：表示使用正则表达式进行匹配。请注意，  此命令会和“全路径”进行匹配，也就是说前面要加.*，因为输出结果中会有“./”符号。 </p>
<p>7. 如果想全部输出用find命令查找出的”*.abc”文件的内容</p>
<h1 id="find-type-f-name-“-abc”-exec-cat"><a href="#find-type-f-name-“-abc”-exec-cat" class="headerlink" title="find . -type f -name “*.abc” -exec cat {} \;"></a>find . -type f -name “*.abc” -exec cat {} \;</h1><p>-exec 表示由find找到的匹配项会作为“-exec后面设定的命令”的参数 </p>
<p>可以使用-ok代替-exec，这样对每个匹配项进行操作，都会要求用户确认（y为是，n为否）</p>
<p>命令最后的{} \; 别忘了写，其中{}代表用find查找到的结果中的每一个查找项。</p>
<p>8. 查找当前目录下在10分钟内被修改过的文件</p>
<h1 id="find-mmin-10"><a href="#find-mmin-10" class="headerlink" title="find . -mmin -10"></a>find . -mmin -10</h1><p>访问过用amin，修改过用mmin，文件状态改变过用cmin</p>
<p>精确到分钟的用amin,mmin,cmin，精确到天的用atime,mtime,ctime</p>
<p>在10分钟之内的用-10，在5分钟以上的用＋10</p>
<p>9. 想查找当前目录及子目录下文件大小大于10M的所有文件</p>
<h1 id="find-size-10000000c"><a href="#find-size-10000000c" class="headerlink" title="find . -size +10000000c"></a>find . -size +10000000c</h1><p>-size：表示文件大小，＋表示大于某个数，－表示小于某个数。c表示单位是字节，你可以将c换成k,M,G。 </p>
<p>10. 上述所有的find命令都是查找当前目录及其子目录。如果不想深入到子目录中，而是只查找当前一层目录，则可以：</p>
<h1 id="find-maxdepth-1-name-“-c”"><a href="#find-maxdepth-1-name-“-c”" class="headerlink" title="find .  -maxdepth 1  -name “*.c”"></a>find . <strong> -maxdepth 1 </strong> -name “*.c”</h1><p>11.  ** 查找当前所有目录并排序  </p>
<h1 id="find-type-d-sort"><a href="#find-type-d-sort" class="headerlink" title="** find . -type d | sort"></a>** find . -type d | sort</h1><p>几个混合应用：  </p>
<p><strong> 1.查找磁盘中大于3M的文件：   
</strong> #find . -size +3000k -exec ls -ld {} ;   </p>
<hr>
<p>2.将find出来的东西拷到另一个地方</p>
<hr>
<h1 id="find-c-exec-cp-‘-’-tmp-‘-’"><a href="#find-c-exec-cp-‘-’-tmp-‘-’" class="headerlink" title="find *.c -exec cp ‘{}’ /tmp ‘;’"></a>find *.c -exec cp ‘{}’ /tmp ‘;’</h1><p>3.  避开多个文件夹  </p>
<h1 id="find-test-path-test-test4-o-path-test-test3-prune-o-print"><a href="#find-test-path-test-test4-o-path-test-test3-prune-o-print" class="headerlink" title="find test \( -path test/test4 -o -path test/test3 \) -prune -o -print"></a>find test \( -path test/test4 -o -path test/test3 \) -prune -o -print</h1><p>\ 表示引用 shell不会对\后面的字符做特殊解释，而留给find命令去解释其意义。<br>不查找test4  和 test3  </p>

        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    
        <a href="https://www.itchina.top/2018/04/20/Linux命令之find/#comments" id="sourceId::2018/04/20/Linux命令之find/" class="article-comment-link cy_cmt_count">评论</a>
    

        </footer>
    </div>
    
</article>



    <article id="post-lombok的使用和原理" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 itemprop="name">
            <a class="article-title" href="/2018/04/20/lombok的使用和原理/">lombok的使用和原理</a>
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/2018/04/20/lombok的使用和原理/">
            <time datetime="2018-04-19T16:34:21.424Z" itemprop="datePublished">2018-04-20</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/IDE/">IDE</a>
    </div>

                        
    <div class="article-tag">
        <i class="fa fa-tag"></i>
        <a class="tag-link" href="/tags/java/">java</a>, <a class="tag-link" href="/tags/lombok/">lombok</a>
    </div>

                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <h1 id="一、项目背景"><a href="#一、项目背景" class="headerlink" title="一、项目背景"></a>一、项目背景</h1><p>在写Java程序的时候经常会遇到如下情形：<br>新建了一个Class类，然后在其中设置了几个字段，最后还需要花费很多时间来建立getter和setter方法<br>lombok项目的产生就是为了省去我们手动创建getter和setter方法的麻烦，它能够在我们编译源码的时候自动帮我们生成getter和setter方法。<br>即它最终能够达到的效果是：在源码中没有getter和setter方法，但是在编译生成的字节码文件中有getter和setter方法<br>比如源码文件：</p>
<pre><code>import java.io.Serializable;
import lombok.Data;

@Data
public class BasicClusterInfo implements Serializable {

    private static final long serialVersionUID = 3478135817352393604L;
    private String hbaseKey;
    private int receiverCount;
}
</code></pre><p>以下是编译上述源码文件得到的字节码文件，对其反编译得到的结果</p>
<pre><code>public class BasicClusterInfo extends java.lang.Object implements java.io.Serializable{
    public BasicClusterInfo();
    public java.lang.String getHbaseKey();
    public int getReceiverCount();
    public void setHbaseKey(java.lang.String);
    public void setReceiverCount(int);
    public boolean equals(java.lang.Object);
    public boolean canEqual(java.lang.Object);
    public int hashCode();
    public java.lang.String toString();
}
</code></pre><h1 id="二、使用方法"><a href="#二、使用方法" class="headerlink" title="二、使用方法"></a>二、使用方法</h1><p>lombok网址： <a href="https://projectlombok.org/download.html" target="_blank" rel="noopener"> https://projectlombok.org/download.html
</a><br>Eclipse支持需要点击运行下载的jar包<br>Maven依赖：</p>
<pre><code>&lt;dependency&gt;        
  &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;        
  &lt;artifactId&gt;lombok&lt;/artifactId&gt;            
  &lt;version&gt;1.16.20&lt;/version&gt;
&lt;/dependency&gt;
</code></pre><p>使用lombok项目的方法很简单，分为四个步骤：<br>1. 在需要自动生成getter和setter方法的类上，加上@Data注解<br>2. 在编译类路径中加入lombok.jar包<br>3. 使用支持lombok的编译工具编译源代码（关于支持lombok的编译工具，见“四、支持lombok的编译工具”）<br>4. 编译得到的字节码文件中自动生成了getter和setter方法</p>
<h1 id="三、原理分析"><a href="#三、原理分析" class="headerlink" title="三、原理分析"></a>三、原理分析</h1><p>接下来进行lombok能够工作的原理分析，以Oracle的javac编译工具为例。<br>自从Java 6起，javac就支持“JSR 269 Pluggable Annotation Processing<br>API”规范，只要程序实现了该API，就能在javac运行的时候得到调用。<br>举例来说，现在有一个实现了”JSR 269 API”的程序A,那么使用javac编译源码的时候具体流程如下：<br>1) javac对源代码进行分析，生成一棵抽象语法树(AST)<br>2) 运行过程中调用实现了”JSR 269 API”的A程序<br>3) 此时A程序就可以完成它自己的逻辑，包括修改第一步骤得到的抽象语法树(AST)<br>4) javac使用修改后的抽象语法树(AST)生成字节码文件<br>详细的流程图如下：</p>
<p><img src="https://img-blog.csdn.net/20180122225319871?watermark/2/text/aHR0cDovL2Jsb
2cuY3Nkbi5uZXQvbHN5MDkwMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/disso
lve/70/gravity/SouthEast" alt=""></p>
<p>lombok本质上就是这样的一个实现了”JSR 269 API”的程序。在使用javac的过程中，它产生作用的具体流程如下：<br>1)javac对源代码进行分析，生成一棵抽象语法树(AST)<br>2)运行过程中调用实现了”JSR 269 API”的lombok程序<br>3)此时lombok就对第一步骤得到的AST进行处理，找到@Data注解所在类对应的语法树(AST)，然后修改该语法树(AST)，增加getter和sett<br>er方法定义的相应树节点<br>4)javac使用修改后的抽象语法树(AST)生成字节码文件  </p>
<h1 id="四、支持lombok的编译工具"><a href="#四、支持lombok的编译工具" class="headerlink" title="四、支持lombok的编译工具"></a>四、支持lombok的编译工具</h1><ol>
<li>由“三、原理分析”可知，Oracle javac直接支持lombok </li>
<li>常用的项目管理工具Maven所使用的java编译工具来源于配置的第三方工具，如果我们配置这个第三方工具为Oracle javac的话，那么Maven也就直接支持lombok了 </li>
<li>Intellij Idea配置的编译工具为Oracle javac的话，也就直接支持lombok了。 </li>
<li>Eclipse中使用的不是Oracle javac这个编译工具，而是自己实现的Eclipse Compiler for Java (ECJ).要想使ECJ支持lombok，得进行设置，具体是在Eclipse程序目录中的eclipse.ini文件中添加如下两行设置：<br>-javaagent:[lombok.jar所在路径]<br>-Xbootclasspath/a:[lombok.jar所在路径] </li>
</ol>
<h1 id="五、其他问题"><a href="#五、其他问题" class="headerlink" title="五、其他问题"></a>五、其他问题</h1><p>现在使用Intellij Idea作为Java项目的IDE，配置Oracle javac作为编译工具。<br>现在有一个A类，其中有一些字段，没有创建它们的setter和getter方法，使用了lombok的@Data注解，另外有一个B类，它调用了A类实例的相应字段<br>的setter和getter方法 。<br>编译A类和B类所在的项目，并不会报错，因为最终生成的A类字节码文件中存在相应字段的setter和getter方法 。<br>但是，IDE发现B类源代码中所使用的A类实例的setter和getter方法在A类源代码中找不到定义，IDE会认为这是错误 。<br>要解决以上这个不是真正错误的错误，可以下载安装Intellij Idea中的”Lombok plugin”。</p>
<h1 id="六、lombok的罪恶"><a href="#六、lombok的罪恶" class="headerlink" title="六、lombok的罪恶"></a>六、lombok的罪恶</h1><p>使用lombok虽然能够省去手动创建setter和getter方法的麻烦，但是却大大降低了源代码文件的可读性和完整性，降低了阅读源代码的舒适度。</p>
<h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><ul>
<li><a href="http://stackoverflow.com/questions/6107197/how-does-lombok-work" target="_blank" rel="noopener"> http://stackoverflow.com/questions/6107197/how-does-lombok-work </a></li>
<li><a href="https://projectlombok.org/download.html" target="_blank" rel="noopener"> https://projectlombok.org/download.html </a></li>
<li><a href="http://stackoverflow.com/questions/3061654/what-is-the-difference-between-javac-and-the-eclipse-compiler" target="_blank" rel="noopener"> http://stackoverflow.com/questions/3061654/what-is-the-difference-between-javac-and-the-eclipse-compiler </a></li>
<li><a href="http://www.ibm.com/developerworks/library/j-lombok/" target="_blank" rel="noopener"> http://www.ibm.com/developerworks/library/j-lombok/ </a></li>
<li><a href="http://notatube.blogspot.com/2010/12/project-lombok-creating-custom.html" target="_blank" rel="noopener"> http://notatube.blogspot.com/2010/12/project-lombok-creating-custom.html </a></li>
</ul>

        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    
        <a href="https://www.itchina.top/2018/04/20/lombok的使用和原理/#comments" id="sourceId::2018/04/20/lombok的使用和原理/" class="article-comment-link cy_cmt_count">评论</a>
    

        </footer>
    </div>
    
</article>



    <article id="post-JBoss 配置windows服务" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 itemprop="name">
            <a class="article-title" href="/2018/04/20/JBoss 配置windows服务/">JBoss 配置windows服务</a>
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/2018/04/20/JBoss 配置windows服务/">
            <time datetime="2018-04-19T16:34:21.423Z" itemprop="datePublished">2018-04-20</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/集群/">集群</a>
    </div>

                        
    <div class="article-tag">
        <i class="fa fa-tag"></i>
        <a class="tag-link" href="/tags/jboss/">jboss</a>, <a class="tag-link" href="/tags/server/">server</a>, <a class="tag-link" href="/tags/windows/">windows</a>
    </div>

                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <p>将Jboss server 配置成一个windows启动服务的两个文件，部署步骤如下：  </p>
<ol>
<li><p>先检查是否配置java_home和jboss_home的环境变量，如没配置上先配置，如我的是JBOSS_HOME=D:\jboss-<br>as-7.1.1.Final。  </p>
</li>
<li><p>将jbosssvc.exe和service.bat文件拷贝到%JBOSS_HOME%\bin 目录下，如我的D:\jboss-<br>as-7.1.1.Final\bin。  </p>
</li>
<li><p>开始－〉运行－〉输入”cmd”，进入命令行，调整目录到%JBOSS_HOME%\bin,如”cd D:\jboss-<br>as-7.1.1.Final\bin”  </p>
</li>
<li><p>在命令行中输入 “service.bat install ”，对服务进行安装。提示” Service JBoss7 installed”表示安装<br>成功。可在开始－〉运行－〉输入services.msc，进入服务列表中，查看到名称是Jboss7的服务。右键Jboss7服务－〉属性－〉常规选项卡－〉启动类<br>型改成自动。自此，每次重新计算机时，jboss7服务随机器自动启动。  </p>
</li>
<li><p>注销jboss服务的方法同上，使用命令” service.bat uninstall ”。  </p>
</li>
</ol>
<p>6．上面提到的两个文件，是从 <a href="http://www.jboss.org/jbossweb/downloads/jboss-
native-2-0-10.html" target="_blank" rel="noopener"> http://www.jboss.org/jbossweb/downloads/jboss-<br>native-2-0-10.html </a> 中，下载binaries 2.0.10-windows x86得到。jboss配置成service.zip  </p>
<p>修改service.bat的启动内容，修改内容如下：  </p>
<p>a. 第21-23行修改服务的名称、显示名称、描述内容  </p>
<p>set SVCNAME=JBoss7server  </p>
<p>set SVCDISP=JBoss7  </p>
<p>set SVCDESC=JBoss AS 7.1.1.Final - Windows x86  </p>
<p>b. 第27行注释掉，在set JAVA_OPTS=-Xrs 的前面加REM，该行改为REM set JAVA_OPTS=-Xrx  注释set<br>JAVA_OPTS=-Xrs的原因是，原本加这一行的作用是防止机算机用户注销时使jboss服务器停止，现注释掉就是指用户注销时jboss就停掉。  </p>
<p>c.全文替换掉 run.bat为standalone.bat，run.log<br>为standalone.log。此替换是为了重定向到手工启动jboss服务器的单机模式。  </p>
<p>7. 64位的服务器需重新下载支持64位的jbosssvc.exe，下载地址如下： <a href="http://www.jboss.org/jbossweb/downloads/jboss-native-2-0-10.html" target="_blank" rel="noopener"><br>http://www.jboss.org/jbossweb/downloads/jboss-native-2-0-10.html
</a><br>中，下载binaries 2.0.10-windows x64。</p>

        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    
        <a href="https://www.itchina.top/2018/04/20/JBoss 配置windows服务/#comments" id="sourceId::2018/04/20/JBoss 配置windows服务/" class="article-comment-link cy_cmt_count">评论</a>
    

        </footer>
    </div>
    
</article>



    <article id="post-Java 异常处理的误区和经验总结" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 itemprop="name">
            <a class="article-title" href="/2018/04/20/Java 异常处理的误区和经验总结/">Java 异常处理的误区和经验总结</a>
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/2018/04/20/Java 异常处理的误区和经验总结/">
            <time datetime="2018-04-19T16:34:21.422Z" itemprop="datePublished">2018-04-20</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/J2EE/">J2EE</a>
    </div>

                        
    <div class="article-tag">
        <i class="fa fa-tag"></i>
        <a class="tag-link" href="/tags/exception/">exception</a>, <a class="tag-link" href="/tags/java/">java</a>, <a class="tag-link" href="/tags/异常/">异常</a>, <a class="tag-link" href="/tags/异常处理/">异常处理</a>
    </div>

                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <p>本文着重介绍了 Java 异常选择和使用中的一些误区，希望各位读者能够熟练掌握异常处理的一些注意点和原则，注意总结和归纳。只有处理好了异常，才能提升开发人员<br>的基本素养，提高系统的健壮性，提升用户体验，提高产品的价值。</p>
<h2 id="误区一、异常的选择"><a href="#误区一、异常的选择" class="headerlink" title="误区一、异常的选择"></a>误区一、异常的选择</h2><h5 id="图-1-异常分类"><a href="#图-1-异常分类" class="headerlink" title="图 1. 异常分类"></a>图 1. 异常分类</h5><p><img src="https://www.ibm.com/developerworks/cn/java/j-lo-exception-
misdirection/img001.png" alt="图 1. 异常分类"></p>
<p>图 1 描述了异常的结构，其实我们都知道异常分检测异常和非检测异常，但是在实际中又混淆了这两种异常的应用。由于非检测异常使用方便，很多开发人员就认为检测异常<br>没什么用处。其实异常的应用情景可以概括为以下：</p>
<p>一、调用代码不能继续执行，需要立即终止。出现这种情况的可能性太多太多，例如服务器连接不上、参数不正确等。这些时候都适用非检测异常，不需要调用代码的显式捕捉和<br>处理，而且代码简洁明了。</p>
<p>二、调用代码需要进一步处理和恢复。假如将 SQLException 定义为非检测异常，这样操作数据时开发人员理所当然的认为 SQLException<br>不需要调用代码的显式捕捉和处理，进而会导致严重的 Connection 不关闭、Transaction 不回滚、DB 中出现脏数据等情况，正因为<br>SQLException 定义为检测异常，才会驱使开发人员去显式捕捉，并且在代码产生异常后清理资源。当然清理资源后，可以继续抛出非检测异常，阻止程序的执行。<br>根据观察和理解，检测异常大多可以应用于工具类中。</p>
<h2 id="误区二、将异常直接显示在页面或客户端。"><a href="#误区二、将异常直接显示在页面或客户端。" class="headerlink" title="误区二、将异常直接显示在页面或客户端。"></a>误区二、将异常直接显示在页面或客户端。</h2><p>将异常直接打印在客户端的例子屡见不鲜，以 JSP 为例，一旦代码运行出现异常，默认情况下容器将异常堆栈信息直接打印在页面上。其实从客户角度来说，任何异常都没<br>有实际意义，绝大多数的客户也根本看不懂异常信息，软件开发也要尽量避免将异常直接呈现给用户。</p>
<h5 id="清单-1"><a href="#清单-1" class="headerlink" title="清单 1"></a>清单 1</h5><pre><code>package com.yctech.org.sample.exception;
/**
 * 自定义 RuntimeException
 * 添加错误代码属性
 */
public class RuntimeException extends java.lang.RuntimeException { 
     //默认错误代码 
    public static final Integer GENERIC = 1000000; 
    //错误代码
    private Integer errorCode; 
     public RuntimeException(Integer errorCode, Throwable cause) {
            this(errorCode, null, cause);
     }
     public RuntimeException(String message, Throwable cause) {
            //利用通用错误代码
            this(GENERIC, message, cause);
     }
     public RuntimeException(Integer errorCode, String message, Throwable cause) {
            super(message, cause);
            this.errorCode = errorCode;
     }
     public Integer getErrorCode() {
            return errorCode;
     } 
}
</code></pre><p>正如示例代码所示，在异常中引入错误代码，一旦出现异常，我们只要将异常的错误代码呈现给用户，或者将错误代码转换成更通俗易懂的提示。其实这里的错误代码还包含另外<br>一个功能，开发人员亦可以根据错误代码准确的知道了发生了什么类型异常。  </p>
<h2 id="误区三、对代码层次结构的污染"><a href="#误区三、对代码层次结构的污染" class="headerlink" title="误区三、对代码层次结构的污染"></a>误区三、对代码层次结构的污染</h2><p>我们经常将代码分 Service、Business Logic、DAO 等不同的层次结构，DAO 层中会包含抛出异常的方法，如清单 2 所示：</p>
<h5 id="清单-2"><a href="#清单-2" class="headerlink" title="清单 2"></a>清单 2</h5><pre><code>public Customer retrieveCustomerById(Long id) throw SQLException {
 //根据 ID 查询数据库
}
</code></pre><p>上面这段代码咋一看没什么问题，但是从设计耦合角度仔细考虑一下，这里的 SQLException 污染到了上层调用代码，调用层需要显式的利用 try-<br>catch 捕捉，或者向更上层次进一步抛出。根据设计隔离原则，我们可以适当修改成：</p>
<h5 id="清单-3"><a href="#清单-3" class="headerlink" title="清单 3"></a>清单 3</h5><pre><code>public Customer retrieveCustomerById(Long id) {
     try{
            //根据 ID 查询数据库
     }catch(SQLException e){
            //利用非检测异常封装检测异常，降低层次耦合
            throw new RuntimeException(SQLErrorCode, e);
     }finally{
            //关闭连接，清理资源
     }
}
</code></pre><h2 id="误区四、忽略异常"><a href="#误区四、忽略异常" class="headerlink" title="误区四、忽略异常"></a>误区四、忽略异常</h2><p>如下异常处理只是将异常输出到控制台，没有任何意义。而且这里出现了异常并没有中断程序，进而调用代码继续执行，导致更多的异常。</p>
<h5 id="清单-4"><a href="#清单-4" class="headerlink" title="清单 4"></a>清单 4</h5><pre><code> public void retrieveObjectById(Long id){
   try{
       //..some code that throws SQLException
    }catch(SQLException ex){
     /**
       *了解的人都知道，这里的异常打印毫无意义，仅仅是将错误堆栈输出到控制台。
       * 而在 Production 环境中，需要将错误堆栈输出到日志。
       * 而且这里 catch 处理之后程序继续执行，会导致进一步的问题*/

          ex.printStacktrace();
     }
}
</code></pre><p>可以重构成：</p>
<h5 id="清单-5"><a href="#清单-5" class="headerlink" title="清单 5"></a>清单 5</h5><pre><code>public void retrieveObjectById(Long id){
 try{
    //..some code that throws SQLException
 }
 catch(SQLException ex){
    throw new RuntimeException(“Exception in retieveObjectById”, ex);
 }
 finally{
    //clean up resultset, statement, connection etc
 }
}
</code></pre><p>这个误区比较基本，一般情况下都不会犯此低级错误。</p>
<h2 id="误区五、将异常包含在循环语句块中"><a href="#误区五、将异常包含在循环语句块中" class="headerlink" title="误区五、将异常包含在循环语句块中"></a>误区五、将异常包含在循环语句块中</h2><p>如下代码所示，异常包含在 for 循环语句块中。</p>
<h5 id="清单-6"><a href="#清单-6" class="headerlink" title="清单 6"></a>清单 6</h5><pre><code>for(int i=0; i&lt;100; i++){
    try{
    }catch(XXXException e){
         //….
    }
}
</code></pre><p>我们都知道异常处理占用系统资源。一看，大家都认为不会犯这样的错误。换个角度，类 A 中执行了一段循环，循环中调用了 B 类的方法，B<br>类中被调用的方法却又包含 try-catch 这样的语句块。褪去类的层次结构，代码和上面如出一辙。</p>
<h2 id="误区六、利用-Exception-捕捉所有潜在的异常"><a href="#误区六、利用-Exception-捕捉所有潜在的异常" class="headerlink" title="误区六、利用 Exception 捕捉所有潜在的异常"></a>误区六、利用 Exception 捕捉所有潜在的异常</h2><p>一段方法执行过程中抛出了几个不同类型的异常，为了代码简洁，利用基类 Exception 捕捉所有潜在的异常，如下例所示：</p>
<h5 id="清单-7"><a href="#清单-7" class="headerlink" title="清单 7"></a>清单 7</h5><pre><code>public void retrieveObjectById(Long id){
    try{
        //…抛出 IOException 的代码调用
        //…抛出 SQLException 的代码调用
    }catch(Exception e){
        //这里利用基类 Exception 捕捉的所有潜在的异常，如果多个层次这样捕捉，会丢失原始异常的有效信息
        throw new RuntimeException(“Exception in retieveObjectById”, e);
    }
}
</code></pre><p>可以重构成</p>
<h5 id="清单-8"><a href="#清单-8" class="headerlink" title="清单 8"></a>清单 8</h5><pre><code>public void retrieveObjectById(Long id){
    try{
        //..some code that throws RuntimeException, IOException, SQLException
    }catch(IOException e){
        //仅仅捕捉 IOException
        throw new RuntimeException(/*指定这里 IOException 对应的错误代码*/code,“Exception in retieveObjectById”, e);
    }catch(SQLException e){
        //仅仅捕捉 SQLException
        throw new RuntimeException(/*指定这里 SQLException 对应的错误代码*/code,“Exception in retieveObjectById”, e);
    }
}
</code></pre><h2 id="误区七、多层次封装抛出非检测异常"><a href="#误区七、多层次封装抛出非检测异常" class="headerlink" title="误区七、多层次封装抛出非检测异常"></a>误区七、多层次封装抛出非检测异常</h2><p>如果我们一直坚持不同类型的异常一定用不同的捕捉语句，那大部分例子可以绕过这一节了。但是如果仅仅一段代码调用会抛出一种以上的异常时，很多时候没有必要每个不同类<br>型的 Exception 写一段 catch 语句，对于开发来说，任何一种异常都足够说明了程序的具体问题。</p>
<h5 id="清单-9"><a href="#清单-9" class="headerlink" title="清单 9"></a>清单 9</h5><pre><code>try{
    //可能抛出 RuntimeException、IOExeption 或者其它；
    //注意这里和误区六的区别，这里是一段代码抛出多种异常。以上是多段代码，各自抛出不同的异常
}catch(Exception e){
    //一如既往的将 Exception 转换成 RuntimeException，但是这里的 e 其实是 RuntimeException 的实例，已经在前段代码中封装过
    throw new RuntimeException(/**/code, /**/, e);
}
</code></pre><p>如果我们如上例所示，将所有的 Exception 再转换成 RuntimeException，那么当 Exception 的类型已经是<br>RuntimeException 时，我们又做了一次封装。将 RuntimeException 又重新封装了一次，进而丢失了原有的<br>RuntimeException 携带的有效信息。</p>
<p>解决办法是我们可以在 RuntimeException 类中添加相关的检查，确认参数 Throwable 不是 RuntimeException<br>的实例。如果是，将拷贝相应的属性到新建的实例上。或者用不同的 catch 语句块捕捉 RuntimeException 和其它的<br>Exception。个人偏好方式一，好处不言而喻。</p>
<h2 id="误区八、多层次打印异常"><a href="#误区八、多层次打印异常" class="headerlink" title="误区八、多层次打印异常"></a>误区八、多层次打印异常</h2><p>我们先看一下下面的例子，定义了 2 个类 A 和 B。其中 A 类中调用了 B 类的代码，并且 A 类和 B 类中都捕捉打印了异常。</p>
<h5 id="清单-10"><a href="#清单-10" class="headerlink" title="清单 10"></a>清单 10</h5><pre><code> public class A {
 private static Logger logger = LoggerFactory.getLogger(A.class);
 public void process(){
     try{
     //实例化 B 类，可以换成其它注入等方式
     B b = new B();
     b.process();
     //other code might cause exception
    } catch(XXXException e){
       //如果 B 类 process 方法抛出异常，异常会在 B 类中被打印，在这里也会被打印，从而会打印 2 次
       logger.error(e);
       throw new RuntimeException(/* 错误代码 */ errorCode, /*异常信息*/msg, e);
       }
    }
}
public class B{
 private static Logger logger = LoggerFactory.getLogger(B.class);
    public void process(){
        try{
            //可能抛出异常的代码
        }
        catch(XXXException e){
            logger.error(e);
            throw new RuntimeException(/* 错误代码 */ errorCode, /*异常信息*/msg, e);
        }
 }
}
</code></pre><p>同一段异常会被打印 2 次。如果层次再复杂一点，不去考虑打印日志消耗的系统性能，仅仅在异常日志中去定位异常具体的问题已经够头疼的了。</p>
<p>其实打印日志只需要在代码的最外层捕捉打印就可以了，异常打印也可以写成 AOP，织入到框架的最外层。</p>
<h2 id="误区九、异常包含的信息不能充分定位问题"><a href="#误区九、异常包含的信息不能充分定位问题" class="headerlink" title="误区九、异常包含的信息不能充分定位问题"></a>误区九、异常包含的信息不能充分定位问题</h2><p>异常不仅要能够让开发人员知道哪里出了问题，更多时候开发人员还需要知道是什么原因导致的问题，我们知道 java .lang.Exception<br>有字符串类型参数的构造方法，这个字符串可以自定义成通俗易懂的提示信息。</p>
<p>简单的自定义信息开发人员只能知道哪里出现了异常，但是很多的情况下，开发人员更需要知道是什么参数导致了这样的异常。这个时候我们就需要将方法调用的参数信息追加到<br>自定义信息中。下例只列举了一个参数的情况，多个参数的情况下，可以单独写一个工具类组织这样的字符串。</p>
<h5 id="清单-11"><a href="#清单-11" class="headerlink" title="清单 11"></a>清单 11</h5><pre><code>public void retieveObjectById(Long id){
    try{
        //..some code that throws SQLException
   }catch(SQLException ex){
        //将参数信息添加到异常信息中
        throw new RuntimeException(“Exception in retieveObjectById with Object Id :”+ id, ex);
   }
}
</code></pre><h2 id="误区十、不能预知潜在的异常"><a href="#误区十、不能预知潜在的异常" class="headerlink" title="误区十、不能预知潜在的异常"></a>误区十、不能预知潜在的异常</h2><p>在写代码的过程中，由于对调用代码缺乏深层次的了解，不能准确判断是否调用的代码会产生异常，因而忽略处理。在产生了 Production Bug 之后才想起来应<br>该在某段代码处添加异常补捉，甚至不能准确指出出现异常的原因。这就需要开发人员不仅知道自己在做什么，而且要去尽可能的知道别人做了什么，可能会导致什么结果，从全<br>局去考虑整个应用程序的处理过程。这些思想会影响我们对代码的编写和处理</p>
<p>##</p>
<p>##</p>
<h2 id="误区十一、混用多种第三方日志库"><a href="#误区十一、混用多种第三方日志库" class="headerlink" title="误区十一、混用多种第三方日志库"></a>误区十一、混用多种第三方日志库</h2><p>现如今 Java 第三方日志库的种类越来越多，一个大项目中会引入各种各样的框架，而这些框架又会依赖不同的日志库的实现。最麻烦的问题倒不是引入所有需要的这些日<br>志库，问题在于引入的这些日志库之间本身不兼容。如果在项目初期可能还好解决，可以把所有代码中的日志库根据需要重新引入一遍，或者换一套框架。但这样的成本不是每个<br>项目都承受的起的，而且越是随着项目的进行，这种风险就越大。</p>
<p>怎么样才能有效的避免类似的问题发生呢，现在的大多数框架已经考虑到了类似的问题，可以通过配置 Properties 或 xml 文件、参数或者运行时扫描<br>Lib 库中的日志实现类，真正在应用程序运行时才确定具体应用哪个特定的日志库。</p>
<p>其实根据不需要多层次打印日志那条原则，我们就可以简化很多原本调用日志打印代码的类。很多情况下，我们可以利用拦截器或者过滤器实现日志的打印，降低代码维护、迁移<br>的成本。</p>
<p>_ _</p>
<h2 id="结束语"><a href="#结束语" class="headerlink" title="结束语"></a>结束语</h2><p>以上纯属个人的经验和总结，事物都是辩证的，没有绝对的原则，适合自己的才是最有效的原则。希望以上的讲解和分析可以对您有所帮助。</p>

        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    
        <a href="https://www.itchina.top/2018/04/20/Java 异常处理的误区和经验总结/#comments" id="sourceId::2018/04/20/Java 异常处理的误区和经验总结/" class="article-comment-link cy_cmt_count">评论</a>
    

        </footer>
    </div>
    
</article>



    <article id="post-idea插件推荐" class="article article-type-post" itemscope itemprop="blogPost">
    <div class="article-inner">
        
        
            <header class="article-header">
                
    
        <h1 itemprop="name">
            <a class="article-title" href="/2018/04/20/idea插件推荐/">idea插件推荐</a>
        </h1>
    

                
                    <div class="article-meta">
                        
    <div class="article-date">
        <i class="fa fa-calendar"></i>
        <a href="/2018/04/20/idea插件推荐/">
            <time datetime="2018-04-19T16:34:21.421Z" itemprop="datePublished">2018-04-20</time>
        </a>
    </div>


                        
    <div class="article-category">
    	<i class="fa fa-folder"></i>
        <a class="article-category-link" href="/categories/IDE/">IDE</a>
    </div>

                        
                    </div>
                
            </header>
        
        
        <div class="article-entry" itemprop="articleBody">
        
            
            <p>推荐一些好(zhuang)用(bi)的IDEA插件</p>
<p>1、Alibaba Java Coding Guidelines</p>
<p>用于扫描代码是否符合阿里巴巴开发规范</p>
<p>该插件由阿里巴巴 P3C 项目组研发。</p>
<p>代码已经开源，GitHub： <a href="https://github.com/alibaba/p3c" target="_blank" rel="noopener"> https://github.com/alibaba/p3c
</a><br>阿里介绍文章： <a href="https://mp.weixin.qq.com/s/IbibsXlWHlM59kfXJqRvZA#rd" target="_blank" rel="noopener"> https://mp.weixin.qq.com/s/IbibsXlWHlM59kfXJqRvZA#rd
</a></p>
<p>插件支持了IDEA、Eclipse，在扫描代码后，将不符合规约的代码显示出来，甚至在 IDEA 上，还基于 Inspection<br>机制提供了实时检测功能，编写代码的同时也能快速发现问题所在，还实现了批量一键修复的功能。</p>
<p><img src="https://img-blog.csdn.net/20180206153323484?watermark/2/text/aHR0cDovL2Jsb
2cuY3Nkbi5uZXQvbHN5MDkwMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/disso
lve/70/gravity/SouthEast" alt=""> <img src="https://img-blog.csdn.net/20180206153348753?wate
rmark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHN5MDkwMw==/font/5a6L5L2T/fontsize/4
00/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt=""></p>
<p>解释下  Blocker/Critical/Major  三个等级，  在 Snoar 中对代码规则有五个级别，这是前三个：崩溃/严重/重要<br>，也就是说前两级别是必须要处理掉的。</p>
<p>版权印为您的作品印上版权87546940  </p>

        
        </div>
        <footer class="article-footer">
            <div class="share-container">


    <div class="bdsharebuttonbox">
    <a href="#" class="bds_more" data-cmd="more">分享到：</a>
    <a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间">QQ空间</a>
    <a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博">新浪微博</a>
    <a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博">腾讯微博</a>
    <a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网">人人网</a>
    <a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信">微信</a>
</div>
<script>
window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{"bdSize":16}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
</script>
<style>
    .bdshare_popup_box {
        border-radius: 4px;
        border: #e1e1e1 solid 1px;
    }
    .bdshare-button-style0-16 a,
    .bdshare-button-style0-16 .bds_more {
        padding-left: 20px;
        margin: 6px 10px 6px 0;
    }
    .bdshare_dialog_list a,
    .bdshare_popup_list a,
    .bdshare_popup_bottom a {
        font-family: 'Microsoft Yahei';
    }
    .bdshare_popup_top {
        display: none;
    }
    .bdshare_popup_bottom {
        height: auto;
        padding: 5px;
    }
</style>


</div>

            
    
        <a href="https://www.itchina.top/2018/04/20/idea插件推荐/#comments" id="sourceId::2018/04/20/idea插件推荐/" class="article-comment-link cy_cmt_count">评论</a>
    

        </footer>
    </div>
    
</article>



    <nav id="page-nav">
        <a class="extend prev" rel="prev" href="/page/3/">&laquo; 上一页</a><a class="page-number" href="/">1</a><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><span class="page-number current">4</span><a class="page-number" href="/page/5/">5</a><a class="page-number" href="/page/6/">6</a><a class="page-number" href="/page/7/">7</a><a class="extend next" rel="next" href="/page/5/">下一页 &raquo;</a>
    </nav>
</section>
            
                
<aside id="sidebar">
   
        
    <div class="widget-wrap">
        <h3 class="widget-title">最新文章</h3>
        <div class="widget">
            <ul id="recent-post" class="no-thumbnail">
                
                    <li>
                        
                        <div class="item-inner">
                            <p class="item-category"><a class="article-category-link" href="/categories/IDE/">IDE</a></p>
                            <p class="item-title"><a href="/2018/04/20/项目相关的CVS操作/" class="title">项目相关的CVS操作</a></p>
                            <p class="item-date"><time datetime="2018-04-19T16:34:21.467Z" itemprop="datePublished">2018-04-20</time></p>
                        </div>
                    </li>
                
                    <li>
                        
                        <div class="item-inner">
                            <p class="item-category"><a class="article-category-link" href="/categories/J2EE/">J2EE</a></p>
                            <p class="item-title"><a href="/2018/04/20/图片转换PDF文件/" class="title">图片转换PDF文件</a></p>
                            <p class="item-date"><time datetime="2018-04-19T16:34:21.449Z" itemprop="datePublished">2018-04-20</time></p>
                        </div>
                    </li>
                
                    <li>
                        
                        <div class="item-inner">
                            <p class="item-category"><a class="article-category-link" href="/categories/Spring/">Spring</a></p>
                            <p class="item-title"><a href="/2018/04/20/使用 Spring Data JPA 简化 JPA 开发/" class="title">使用 Spring Data JPA 简化 JPA 开发</a></p>
                            <p class="item-date"><time datetime="2018-04-19T16:34:21.448Z" itemprop="datePublished">2018-04-20</time></p>
                        </div>
                    </li>
                
                    <li>
                        
                        <div class="item-inner">
                            <p class="item-category"></p>
                            <p class="item-title"><a href="/2018/04/20/通过Ajax进行POST提交JSON类型的数据到SpringMVC Controller的方法/" class="title">通过Ajax进行POST提交JSON类型的数据到SpringMVC Controller的方法</a></p>
                            <p class="item-date"><time datetime="2018-04-19T16:34:21.448Z" itemprop="datePublished">2018-04-20</time></p>
                        </div>
                    </li>
                
                    <li>
                        
                        <div class="item-inner">
                            <p class="item-category"></p>
                            <p class="item-title"><a href="/2018/04/20/面试感悟----一名3年工作经验的程序员应该具备的技能/" class="title">面试感悟----一名3年工作经验的程序员应该具备的技能</a></p>
                            <p class="item-date"><time datetime="2018-04-19T16:34:21.447Z" itemprop="datePublished">2018-04-20</time></p>
                        </div>
                    </li>
                
            </ul>
        </div>
    </div>

    
        
    <div class="widget-wrap">
        <h3 class="widget-title">分类</h3>
        <div class="widget">
            <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/ActiveMQ/">ActiveMQ</a><span class="category-list-count">7</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/ExtJs/">ExtJs</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Git/">Git</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/IDE/">IDE</a><span class="category-list-count">4</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/J2EE/">J2EE</a><span class="category-list-count">7</span><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/J2EE/Spring/">Spring</a><span class="category-list-count">1</span></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/Linux/">Linux</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Redis/">Redis</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/Spring/">Spring</a><span class="category-list-count">21</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/cnn图片数据处理、显示/">cnn图片数据处理、显示</a><span class="category-list-count">1</span><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/cnn图片数据处理、显示/python数据分析/">python数据分析</a><span class="category-list-count">1</span></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/web前端/">web前端</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/数据库/">数据库</a><span class="category-list-count">3</span><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/数据库/集群/">集群</a><span class="category-list-count">1</span></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/集群/">集群</a><span class="category-list-count">2</span></li></ul>
        </div>
    </div>

    
        
    <div class="widget-wrap">
        <h3 class="widget-title">归档</h3>
        <div class="widget">
            <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/04/">四月 2018</a><span class="archive-list-count">65</span></li></ul>
        </div>
    </div>

    
        
    <div class="widget-wrap">
        <h3 class="widget-title">标签</h3>
        <div class="widget">
            <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Apache/">Apache</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Docker/">Docker</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Druid/">Druid</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/ImageToPDF/">ImageToPDF</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Logstash/">Logstash</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Spring-Boot/">Spring Boot</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/activemq/">activemq</a><span class="tag-list-count">7</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/ajax/">ajax</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/angular/">angular</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/cas/">cas</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/docker/">docker</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/exception/">exception</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/ext/">ext</a><span class="tag-list-count">3</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/extjs/">extjs</a><span class="tag-list-count">3</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/find/">find</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/git/">git</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/github/">github</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/ide/">ide</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/idea/">idea</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/java/">java</a><span class="tag-list-count">5</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/javascript/">javascript</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/jboss/">jboss</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/jmx/">jmx</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/jpa/">jpa</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/linux/">linux</a><span class="tag-list-count">3</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/lombok/">lombok</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/mvc/">mvc</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/mybatis/">mybatis</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/mysql/">mysql</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/nginx/">nginx</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/numpy/">numpy</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/seo/">seo</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/server/">server</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/shiro/">shiro</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/spring/">spring</a><span class="tag-list-count">17</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/spring-mvc/">spring mvc</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/spring-boo/">spring-boo</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/sql-server/">sql server</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/windows/">windows</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/zookeeper/">zookeeper</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/优化/">优化</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/分布式日志/">分布式日志</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/多线程/">多线程</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/工作/">工作</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/异常/">异常</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/异常处理/">异常处理</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/搜索引擎/">搜索引擎</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/数据分析/">数据分析</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/汉字转拼音/">汉字转拼音</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/版本控制系统/">版本控制系统</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/程序员/">程序员</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/经验/">经验</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/集群/">集群</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/面试/">面试</a><span class="tag-list-count">1</span></li></ul>
        </div>
    </div>

    
        
    <div class="widget-wrap">
        <h3 class="widget-title">标签云</h3>
        <div class="widget tagcloud">
            <a href="/tags/Apache/" style="font-size: 10px;">Apache</a> <a href="/tags/Docker/" style="font-size: 10px;">Docker</a> <a href="/tags/Druid/" style="font-size: 10px;">Druid</a> <a href="/tags/ImageToPDF/" style="font-size: 10px;">ImageToPDF</a> <a href="/tags/Logstash/" style="font-size: 10px;">Logstash</a> <a href="/tags/Spring-Boot/" style="font-size: 10px;">Spring Boot</a> <a href="/tags/activemq/" style="font-size: 18px;">activemq</a> <a href="/tags/ajax/" style="font-size: 10px;">ajax</a> <a href="/tags/angular/" style="font-size: 10px;">angular</a> <a href="/tags/cas/" style="font-size: 10px;">cas</a> <a href="/tags/docker/" style="font-size: 10px;">docker</a> <a href="/tags/exception/" style="font-size: 10px;">exception</a> <a href="/tags/ext/" style="font-size: 14px;">ext</a> <a href="/tags/extjs/" style="font-size: 14px;">extjs</a> <a href="/tags/find/" style="font-size: 10px;">find</a> <a href="/tags/git/" style="font-size: 10px;">git</a> <a href="/tags/github/" style="font-size: 10px;">github</a> <a href="/tags/ide/" style="font-size: 12px;">ide</a> <a href="/tags/idea/" style="font-size: 10px;">idea</a> <a href="/tags/java/" style="font-size: 16px;">java</a> <a href="/tags/javascript/" style="font-size: 12px;">javascript</a> <a href="/tags/jboss/" style="font-size: 10px;">jboss</a> <a href="/tags/jmx/" style="font-size: 10px;">jmx</a> <a href="/tags/jpa/" style="font-size: 10px;">jpa</a> <a href="/tags/linux/" style="font-size: 14px;">linux</a> <a href="/tags/lombok/" style="font-size: 10px;">lombok</a> <a href="/tags/mvc/" style="font-size: 10px;">mvc</a> <a href="/tags/mybatis/" style="font-size: 10px;">mybatis</a> <a href="/tags/mysql/" style="font-size: 12px;">mysql</a> <a href="/tags/nginx/" style="font-size: 10px;">nginx</a> <a href="/tags/numpy/" style="font-size: 10px;">numpy</a> <a href="/tags/seo/" style="font-size: 10px;">seo</a> <a href="/tags/server/" style="font-size: 10px;">server</a> <a href="/tags/shiro/" style="font-size: 12px;">shiro</a> <a href="/tags/spring/" style="font-size: 20px;">spring</a> <a href="/tags/spring-mvc/" style="font-size: 10px;">spring mvc</a> <a href="/tags/spring-boo/" style="font-size: 10px;">spring-boo</a> <a href="/tags/sql-server/" style="font-size: 10px;">sql server</a> <a href="/tags/windows/" style="font-size: 10px;">windows</a> <a href="/tags/zookeeper/" style="font-size: 10px;">zookeeper</a> <a href="/tags/优化/" style="font-size: 12px;">优化</a> <a href="/tags/分布式日志/" style="font-size: 10px;">分布式日志</a> <a href="/tags/多线程/" style="font-size: 10px;">多线程</a> <a href="/tags/工作/" style="font-size: 10px;">工作</a> <a href="/tags/异常/" style="font-size: 10px;">异常</a> <a href="/tags/异常处理/" style="font-size: 10px;">异常处理</a> <a href="/tags/搜索引擎/" style="font-size: 12px;">搜索引擎</a> <a href="/tags/数据分析/" style="font-size: 10px;">数据分析</a> <a href="/tags/汉字转拼音/" style="font-size: 10px;">汉字转拼音</a> <a href="/tags/版本控制系统/" style="font-size: 10px;">版本控制系统</a> <a href="/tags/程序员/" style="font-size: 10px;">程序员</a> <a href="/tags/经验/" style="font-size: 10px;">经验</a> <a href="/tags/集群/" style="font-size: 10px;">集群</a> <a href="/tags/面试/" style="font-size: 10px;">面试</a>
        </div>
    </div>

    
        
    <div class="widget-wrap widget-list">
        <h3 class="widget-title">链接</h3>
        <div class="widget">
            <ul>
                
                    <li>
                        <a href="http://www.baidu.com">百度</a>
                    </li>
                
            </ul>
        </div>
    </div>


    
    <div id="toTop" class="fa fa-angle-up"></div>
</aside>

            
        </div>
        <!--google 底部广告 -->
<div style="width:100%;text-align: center;clear: both;margin-bottom: 20px;" class="hidden-xs">
    <script async src="http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
    <!-- 博客footer上方的广告 -->
    <ins class="adsbygoogle"
         style="display:block"
         data-ad-client="ca-pub-8254913025324557"
         data-ad-slot="3369473724"
         data-ad-format="auto"></ins>
    <script>
        (adsbygoogle = window.adsbygoogle || []).push({});
    </script>
</div>
<footer id="footer">
    <div class="outer">
        <div id="footer-info" class="inner">
            &copy;2018 - 2018&nbsp; LErry Li &nbsp;版权所有<br>
			<a href="http://www.miitbeian.gov.cn">沪ICP备17054498号-3</a>
        </div>
    </div>
</footer>
        
    
    <script id="cy_cmt_num" src="https://changyan.sohu.com/upload/plugins/plugins.list.count.js?clientId=cytxPSIHr"></script>
    <script charset="utf-8" type="text/javascript" src="https://changyan.sohu.com/upload/changyan.js" ></script>
    <script type="text/javascript">
    window.changyan.api.config({
    appid: 'cytxPSIHr',
    conf: 'prod_3c92d05d8ba4377e48c5fe27c2159761'
    });
    </script>




    
        <script src="/libs/lightgallery/js/lightgallery.min.js"></script>
        <script src="/libs/lightgallery/js/lg-thumbnail.min.js"></script>
        <script src="/libs/lightgallery/js/lg-pager.min.js"></script>
        <script src="/libs/lightgallery/js/lg-autoplay.min.js"></script>
        <script src="/libs/lightgallery/js/lg-fullscreen.min.js"></script>
        <script src="/libs/lightgallery/js/lg-zoom.min.js"></script>
        <script src="/libs/lightgallery/js/lg-hash.min.js"></script>
        <script src="/libs/lightgallery/js/lg-share.min.js"></script>
        <script src="/libs/lightgallery/js/lg-video.min.js"></script>
    
    
        <script src="/libs/justified-gallery/jquery.justifiedGallery.min.js"></script>
    
    



<!-- Custom Scripts -->
<script src="/js/main.js"></script>

    </div>
</body>
</html>